From patchwork Fri Mar 4 06:54:17 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bharata B Rao X-Patchwork-Id: 8499601 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id B6D879F659 for ; Fri, 4 Mar 2016 06:59:37 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C9C712010B for ; Fri, 4 Mar 2016 06:59:36 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B072320108 for ; Fri, 4 Mar 2016 06:59:35 +0000 (UTC) Received: from localhost ([::1]:39152 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1abji3-0001qa-67 for patchwork-qemu-devel@patchwork.kernel.org; Fri, 04 Mar 2016 01:59:35 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57398) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1abjdZ-0001y5-ML for qemu-devel@nongnu.org; Fri, 04 Mar 2016 01:54:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1abjdV-0005XT-Ge for qemu-devel@nongnu.org; Fri, 04 Mar 2016 01:54:57 -0500 Received: from e28smtp02.in.ibm.com ([125.16.236.2]:38330) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1abjdU-0005Vm-Hl for qemu-devel@nongnu.org; Fri, 04 Mar 2016 01:54:53 -0500 Received: from localhost by e28smtp02.in.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 4 Mar 2016 12:24:50 +0530 Received: from d28relay04.in.ibm.com (9.184.220.61) by e28smtp02.in.ibm.com (192.168.1.132) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Fri, 4 Mar 2016 12:24:43 +0530 X-IBM-Helo: d28relay04.in.ibm.com X-IBM-MailFrom: bharata@linux.vnet.ibm.com X-IBM-RcptTo: qemu-ppc@nongnu.org;qemu-devel@nongnu.org Received: from d28av03.in.ibm.com (d28av03.in.ibm.com [9.184.220.65]) by d28relay04.in.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u246sZmP7930124; Fri, 4 Mar 2016 12:24:35 +0530 Received: from d28av03.in.ibm.com (localhost [127.0.0.1]) by d28av03.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVout) with ESMTP id u246seDT030059; Fri, 4 Mar 2016 12:24:41 +0530 Received: from bharata.in.ibm.com ([9.124.212.244]) by d28av03.in.ibm.com (8.14.4/8.14.4/NCO v10.0 AVin) with ESMTP id u246sQDW029500; Fri, 4 Mar 2016 12:24:37 +0530 From: Bharata B Rao To: qemu-devel@nongnu.org Date: Fri, 4 Mar 2016 12:24:17 +0530 Message-Id: <1457074461-14285-7-git-send-email-bharata@linux.vnet.ibm.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: <1457074461-14285-1-git-send-email-bharata@linux.vnet.ibm.com> References: <1457074461-14285-1-git-send-email-bharata@linux.vnet.ibm.com> X-TM-AS-MML: disable x-cbid: 16030406-0005-0000-0000-00000AD0F0B5 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 125.16.236.2 Cc: mjrosato@linux.vnet.ibm.com, thuth@redhat.com, pkrempa@redhat.com, ehabkost@redhat.com, aik@ozlabs.ru, Bharata B Rao , armbru@redhat.com, agraf@suse.de, borntraeger@de.ibm.com, qemu-ppc@nongnu.org, pbonzini@redhat.com, imammedo@redhat.com, mdroth@linux.vnet.ibm.com, afaerber@suse.de, david@gibson.dropbear.id.au Subject: [Qemu-devel] [RFC PATCH v1 06/10] spapr: CPU core device X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add sPAPR specific CPU core device that is based on generic CPU core device. Creating this core device will result in creation of all the CPU thread devices that are part of this core. Signed-off-by: Bharata B Rao --- hw/ppc/Makefile.objs | 1 + hw/ppc/spapr_cpu_core.c | 208 ++++++++++++++++++++++++++++++++++++++++ include/hw/ppc/spapr_cpu_core.h | 29 ++++++ 3 files changed, 238 insertions(+) create mode 100644 hw/ppc/spapr_cpu_core.c create mode 100644 include/hw/ppc/spapr_cpu_core.h diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs index c1ffc77..5cc6608 100644 --- a/hw/ppc/Makefile.objs +++ b/hw/ppc/Makefile.objs @@ -4,6 +4,7 @@ obj-y += ppc.o ppc_booke.o obj-$(CONFIG_PSERIES) += spapr.o spapr_vio.o spapr_events.o obj-$(CONFIG_PSERIES) += spapr_hcall.o spapr_iommu.o spapr_rtas.o obj-$(CONFIG_PSERIES) += spapr_pci.o spapr_rtc.o spapr_drc.o spapr_rng.o +obj-$(CONFIG_PSERIES) += spapr_cpu_core.o ifeq ($(CONFIG_PCI)$(CONFIG_PSERIES)$(CONFIG_LINUX), yyy) obj-y += spapr_pci_vfio.o endif diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c new file mode 100644 index 0000000..3f3440c --- /dev/null +++ b/hw/ppc/spapr_cpu_core.c @@ -0,0 +1,208 @@ +/* + * sPAPR CPU core device, acts as container of CPU thread devices. + * + * Copyright (C) 2016 Bharata B Rao + * + * 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 "hw/cpu/core.h" +#include "hw/ppc/spapr_cpu_core.h" +#include "hw/ppc/spapr.h" +#include "hw/boards.h" +#include "qemu/error-report.h" +#include "qapi/visitor.h" +#include + +static int spapr_cpu_core_realize_child(Object *child, void *opaque) +{ + Error **errp = opaque; + + object_property_set_bool(child, true, "realized", errp); + if (*errp) { + return 1; + } + return 0; +} + +static void spapr_cpu_core_realize(DeviceState *dev, Error **errp) +{ + sPAPRCPUCore *core = SPAPR_CPU_CORE(OBJECT(dev)); + sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); + char *slot; + Error *local_err = NULL; + + if (!core->nr_threads) { + error_setg(errp, "nr_threads property can't be 0"); + return; + } + + if (!core->oc) { + error_setg(errp, "cpu_model property isn't set"); + return; + } + + /* + * TODO: If slot isn't specified, plug this core into + * an existing empty slot. + */ + slot = object_property_get_str(OBJECT(dev), CPU_CORE_SLOT_PROP, &local_err); + if (!slot) { + error_setg(errp, "slot property isn't set"); + return; + } + + object_property_set_link(OBJECT(spapr), OBJECT(core), slot, &local_err); + g_free(slot); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + object_child_foreach(OBJECT(dev), spapr_cpu_core_realize_child, errp); +} + +/* + * This creates the CPU threads for a given @core. + * + * In order to create the threads, we need two inputs - number of + * threads and the cpu_model. These are set as core object's properties. + * When both of them become available/set, this routine will be called from + * either property's set handler to create the threads. + * + * TODO: Dependence of threads creation on two properties is resulting + * in this not-so-clean way of creating threads from either of the + * property setters based on the order in which they get set. Check if + * this can be handled in a better manner. + */ +static void spapr_cpu_core_create_threads(sPAPRCPUCore *core, Error **errp) +{ + int i; + Error *local_err = NULL; + + for (i = 0; i < core->nr_threads; i++) { + char id[32]; + + object_initialize(&core->threads[i], sizeof(core->threads[i]), + object_class_get_name(core->oc)); + snprintf(id, sizeof(id), "thread[%d]", i); + object_property_add_child(OBJECT(core), id, OBJECT(&core->threads[i]), + &local_err); + if (local_err) { + goto err; + } + } + return; + +err: + while (--i) { + object_unparent(OBJECT(&core->threads[i])); + } + error_propagate(errp, local_err); +} + +static char *spapr_cpu_core_prop_get_cpu_model(Object *obj, Error **errp) +{ + sPAPRCPUCore *core = SPAPR_CPU_CORE(obj); + + return g_strdup(object_class_get_name(core->oc)); +} + +static void spapr_cpu_core_prop_set_cpu_model(Object *obj, const char *val, + Error **errp) +{ + sPAPRCPUCore *core = SPAPR_CPU_CORE(obj); + MachineState *machine = MACHINE(qdev_get_machine()); + ObjectClass *oc = cpu_class_by_name(TYPE_POWERPC_CPU, val); + ObjectClass *oc_base = cpu_class_by_name(TYPE_POWERPC_CPU, + machine->cpu_model); + if (!oc) { + error_setg(errp, "Unknown CPU model %s", val); + return; + } + + /* + * Currently cpu_model can't be different from what is specified with -cpu + */ + if (strcmp(object_class_get_name(oc), object_class_get_name(oc_base))) { + error_setg(errp, "cpu_model must be %s", machine->cpu_model); + return; + } + + core->oc = oc; + if (core->nr_threads && core->oc) { + spapr_cpu_core_create_threads(core, errp); + } +} + +static void spapr_cpu_core_prop_get_nr_threads(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + sPAPRCPUCore *core = SPAPR_CPU_CORE(obj); + int64_t value = core->nr_threads; + + visit_type_int(v, name, &value, errp); +} + +static void spapr_cpu_core_prop_set_nr_threads(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ + sPAPRCPUCore *core = SPAPR_CPU_CORE(obj); + Error *local_err = NULL; + int64_t value; + + visit_type_int(v, name, &value, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + /* Allow only homogeneous configuration */ + if (value != smp_threads) { + error_setg(errp, "nr_threads must be %d", smp_threads); + return; + } + + core->nr_threads = value; + core->threads = g_new0(PowerPCCPU, core->nr_threads); + + if (core->nr_threads && core->oc) { + spapr_cpu_core_create_threads(core, errp); + } +} + +static void spapr_cpu_core_instance_init(Object *obj) +{ + object_property_add(obj, "nr_threads", "int", + spapr_cpu_core_prop_get_nr_threads, + spapr_cpu_core_prop_set_nr_threads, + NULL, NULL, NULL); + object_property_add_str(obj, "cpu_model", + spapr_cpu_core_prop_get_cpu_model, + spapr_cpu_core_prop_set_cpu_model, + NULL); +} + +static void spapr_cpu_core_class_init(ObjectClass *oc, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(oc); + + dc->realize = spapr_cpu_core_realize; +} + +static const TypeInfo spapr_cpu_core_type_info = { + .name = TYPE_SPAPR_CPU_CORE, + .parent = TYPE_CPU_CORE, + .instance_init = spapr_cpu_core_instance_init, + .instance_size = sizeof(sPAPRCPUCore), + .class_init = spapr_cpu_core_class_init, +}; + +static void spapr_cpu_core_register_types(void) +{ + type_register_static(&spapr_cpu_core_type_info); +} + +type_init(spapr_cpu_core_register_types) diff --git a/include/hw/ppc/spapr_cpu_core.h b/include/hw/ppc/spapr_cpu_core.h new file mode 100644 index 0000000..ddaff6f --- /dev/null +++ b/include/hw/ppc/spapr_cpu_core.h @@ -0,0 +1,29 @@ +/* + * sPAPR CPU core device. + * + * Copyright (C) 2016 Bharata B Rao + * + * 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_SPAPR_CPU_CORE_H +#define HW_SPAPR_CPU_CORE_H + +#include "hw/qdev.h" +#include "hw/cpu/core.h" + +#define TYPE_SPAPR_CPU_CORE "spapr-cpu-core" +#define SPAPR_CPU_CORE(obj) \ + OBJECT_CHECK(sPAPRCPUCore, (obj), TYPE_SPAPR_CPU_CORE) + +typedef struct sPAPRCPUCore { + /*< private >*/ + CPUCore parent_obj; + + /*< public >*/ + int nr_threads; + ObjectClass *oc; + PowerPCCPU *threads; +} sPAPRCPUCore; + +#endif