From patchwork Fri Jun 22 04:24:15 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 933082 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="UU2I2gyC"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Bm3q48cdz9s01 for ; Fri, 22 Jun 2018 14:36:23 +1000 (AEST) Received: from localhost ([::1]:59181 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDo5-0007Rv-88 for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 00:36:21 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39676) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDcy-0007ha-NS for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWDcu-0003Xk-9u for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:52 -0400 Received: from ozlabs.org ([203.11.71.1]:41457) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fWDct-0003XG-II; Fri, 22 Jun 2018 00:24:48 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41BlpM3SC7z9s4s; Fri, 22 Jun 2018 14:24:43 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1529641483; bh=iDq1RdUtodaLl3+YDphUt28ncjQ1vN1Iz0674CDcxkI=; h=From:To:Cc:Subject:Date:From; b=UU2I2gyC6OeUSJoqhg+29kFr7z7HGFNgDR851t8euVYXTQmuQISPZlKdIUHj2J+R0 EiNqXIXCs5vVZuiAedXg+zoWuPnSDLBDeoTqnawp8iWPAhGTvGqfKj/JLnghIWKF9c G+xpk0sENAahTF5yUvrsxKn+s8QEcSwTnew5HFEo= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 22 Jun 2018 14:24:15 +1000 Message-Id: <20180622042437.14259-1-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PATCH 01/23] ppc/pnv: introduce a new intc_create() operation to the chip model X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Cédric Le Goater On Power9, the thread interrupt presenter has a different type and is linked to the chip owning the cores. Signed-off-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/ppc/pnv.c | 21 +++++++++++++++++++-- hw/ppc/pnv_core.c | 18 +++++++++--------- include/hw/ppc/pnv.h | 1 + 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 0d2b79f798..c7e127ae97 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -671,6 +671,13 @@ static uint32_t pnv_chip_core_pir_p8(PnvChip *chip, uint32_t core_id) return (chip->chip_id << 7) | (core_id << 3); } +static Object *pnv_chip_power8_intc_create(PnvChip *chip, Object *child, + Error **errp) +{ + return icp_create(child, TYPE_PNV_ICP, XICS_FABRIC(qdev_get_machine()), + errp); +} + /* * 0:48 Reserved - Read as zeroes * 49:52 Node ID @@ -686,6 +693,12 @@ static uint32_t pnv_chip_core_pir_p9(PnvChip *chip, uint32_t core_id) return (chip->chip_id << 8) | (core_id << 2); } +static Object *pnv_chip_power9_intc_create(PnvChip *chip, Object *child, + Error **errp) +{ + return NULL; +} + /* Allowed core identifiers on a POWER8 Processor Chip : * * @@ -721,6 +734,7 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data) k->chip_cfam_id = 0x221ef04980000000ull; /* P8 Murano DD2.1 */ k->cores_mask = POWER8E_CORE_MASK; k->core_pir = pnv_chip_core_pir_p8; + k->intc_create = pnv_chip_power8_intc_create; k->xscom_base = 0x003fc0000000000ull; dc->desc = "PowerNV Chip POWER8E"; } @@ -734,6 +748,7 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, void *data) k->chip_cfam_id = 0x220ea04980000000ull; /* P8 Venice DD2.0 */ k->cores_mask = POWER8_CORE_MASK; k->core_pir = pnv_chip_core_pir_p8; + k->intc_create = pnv_chip_power8_intc_create; k->xscom_base = 0x003fc0000000000ull; dc->desc = "PowerNV Chip POWER8"; } @@ -747,6 +762,7 @@ static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data) k->chip_cfam_id = 0x120d304980000000ull; /* P8 Naples DD1.0 */ k->cores_mask = POWER8_CORE_MASK; k->core_pir = pnv_chip_core_pir_p8; + k->intc_create = pnv_chip_power8_intc_create; k->xscom_base = 0x003fc0000000000ull; dc->desc = "PowerNV Chip POWER8NVL"; } @@ -760,6 +776,7 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data) k->chip_cfam_id = 0x220d104900008000ull; /* P9 Nimbus DD2.0 */ k->cores_mask = POWER9_CORE_MASK; k->core_pir = pnv_chip_core_pir_p9; + k->intc_create = pnv_chip_power9_intc_create; k->xscom_base = 0x00603fc00000000ull; dc->desc = "PowerNV Chip POWER9"; } @@ -892,8 +909,8 @@ static void pnv_chip_core_realize(PnvChip *chip, Error **errp) object_property_set_int(OBJECT(pnv_core), pcc->core_pir(chip, core_hwid), "pir", &error_fatal); - object_property_add_const_link(OBJECT(pnv_core), "xics", - qdev_get_machine(), &error_fatal); + object_property_add_const_link(OBJECT(pnv_core), "chip", + OBJECT(chip), &error_fatal); object_property_set_bool(OBJECT(pnv_core), true, "realized", &error_fatal); object_unref(OBJECT(pnv_core)); diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index f7cf33f547..a9f129fc2c 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -99,13 +99,14 @@ static const MemoryRegionOps pnv_core_xscom_ops = { .endianness = DEVICE_BIG_ENDIAN, }; -static void pnv_realize_vcpu(PowerPCCPU *cpu, XICSFabric *xi, Error **errp) +static void pnv_realize_vcpu(PowerPCCPU *cpu, PnvChip *chip, Error **errp) { CPUPPCState *env = &cpu->env; int core_pir; int thread_index = 0; /* TODO: TCG supports only one thread */ ppc_spr_t *pir = &env->spr_cb[SPR_PIR]; Error *local_err = NULL; + PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip); object_property_set_bool(OBJECT(cpu), true, "realized", &local_err); if (local_err) { @@ -113,7 +114,7 @@ static void pnv_realize_vcpu(PowerPCCPU *cpu, XICSFabric *xi, Error **errp) return; } - cpu->intc = icp_create(OBJECT(cpu), TYPE_PNV_ICP, xi, &local_err); + cpu->intc = pcc->intc_create(chip, OBJECT(cpu), &local_err); if (local_err) { error_propagate(errp, local_err); return; @@ -143,13 +144,12 @@ static void pnv_core_realize(DeviceState *dev, Error **errp) void *obj; int i, j; char name[32]; - Object *xi; + Object *chip; - xi = object_property_get_link(OBJECT(dev), "xics", &local_err); - if (!xi) { - error_setg(errp, "%s: required link 'xics' not found: %s", - __func__, error_get_pretty(local_err)); - return; + chip = object_property_get_link(OBJECT(dev), "chip", &local_err); + if (!chip) { + error_propagate(errp, local_err); + error_prepend(errp, "required link 'chip' not found: "); } pc->threads = g_new(PowerPCCPU *, cc->nr_threads); @@ -166,7 +166,7 @@ static void pnv_core_realize(DeviceState *dev, Error **errp) } for (j = 0; j < cc->nr_threads; j++) { - pnv_realize_vcpu(pc->threads[j], XICS_FABRIC(xi), &local_err); + pnv_realize_vcpu(pc->threads[j], PNV_CHIP(chip), &local_err); if (local_err) { goto err; } diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h index 90759240a7..e934e84f55 100644 --- a/include/hw/ppc/pnv.h +++ b/include/hw/ppc/pnv.h @@ -76,6 +76,7 @@ typedef struct PnvChipClass { hwaddr xscom_base; uint32_t (*core_pir)(PnvChip *chip, uint32_t core_id); + Object *(*intc_create)(PnvChip *chip, Object *child, Error **errp); } PnvChipClass; #define PNV_CHIP_TYPE_SUFFIX "-" TYPE_PNV_CHIP From patchwork Fri Jun 22 04:24:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 933079 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="YzjTNyjB"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Bm0X6D8gz9s2R for ; Fri, 22 Jun 2018 14:33:32 +1000 (AEST) Received: from localhost ([::1]:59165 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDlK-0005Gt-HW for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 00:33:30 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39628) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDcw-0007go-2U for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWDcu-0003YD-RF for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:50 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:52147) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fWDcu-0003XK-4U; Fri, 22 Jun 2018 00:24:48 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41BlpM58hsz9s52; Fri, 22 Jun 2018 14:24:43 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1529641483; bh=GP49fxwOMDLz1GWA4CmxzLPopI941DzjOsLsKZ17pq4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YzjTNyjBpB/CQU5w5jmuK/0Zq9aGNuuaqjX+4MKc16uWgIZ33rRou+/hUHpYst8Mx DFfBiKBw6YtEAVb+yXiyRIEA6zIWEib3Unh15J5jfLQoHP+TPiaCfekz9AZ7Cnmds2 Bxpj0EWkRInlLWCSSkdWo7CMTga8qM+eboHo2avg= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 22 Jun 2018 14:24:16 +1000 Message-Id: <20180622042437.14259-2-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180622042437.14259-1-david@gibson.dropbear.id.au> References: <20180622042437.14259-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 Subject: [Qemu-devel] [PATCH 02/23] ppc/pnv: introduce a new isa_create() operation to the chip model X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Cédric Le Goater This moves the details of the ISA bus creation under the LPC model but more important, the new PnvChip operation will let us choose the chip class to use when we introduce the different chip classes for Power9 and Power8. It hides away the processor chip controllers from the machine. Signed-off-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/ppc/pnv.c | 34 +++++++++++++++++++--------------- hw/ppc/pnv_lpc.c | 30 +++++++++++++++++++++++++----- include/hw/ppc/pnv.h | 1 + include/hw/ppc/pnv_lpc.h | 3 +-- 4 files changed, 46 insertions(+), 22 deletions(-) diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index c7e127ae97..ac828d1331 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -529,24 +529,24 @@ static void pnv_reset(void) cpu_physical_memory_write(PNV_FDT_ADDR, fdt, fdt_totalsize(fdt)); } -static ISABus *pnv_isa_create(PnvChip *chip) +static ISABus *pnv_chip_power8_isa_create(PnvChip *chip, Error **errp) { - PnvLpcController *lpc = &chip->lpc; - ISABus *isa_bus; - qemu_irq *irqs; - PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip); + return pnv_lpc_isa_create(&chip->lpc, true, errp); +} - /* let isa_bus_new() create its own bridge on SysBus otherwise - * devices speficied on the command line won't find the bus and - * will fail to create. - */ - isa_bus = isa_bus_new(NULL, &lpc->isa_mem, &lpc->isa_io, - &error_fatal); +static ISABus *pnv_chip_power8nvl_isa_create(PnvChip *chip, Error **errp) +{ + return pnv_lpc_isa_create(&chip->lpc, false, errp); +} - irqs = pnv_lpc_isa_irq_create(lpc, pcc->chip_type, ISA_NUM_IRQS); +static ISABus *pnv_chip_power9_isa_create(PnvChip *chip, Error **errp) +{ + return NULL; +} - isa_bus_irqs(isa_bus, irqs); - return isa_bus; +static ISABus *pnv_isa_create(PnvChip *chip, Error **errp) +{ + return PNV_CHIP_GET_CLASS(chip)->isa_create(chip, errp); } static void pnv_init(MachineState *machine) @@ -646,7 +646,7 @@ static void pnv_init(MachineState *machine) g_free(chip_typename); /* Instantiate ISA bus on chip 0 */ - pnv->isa_bus = pnv_isa_create(pnv->chips[0]); + pnv->isa_bus = pnv_isa_create(pnv->chips[0], &error_fatal); /* Create serial port */ serial_hds_isa_init(pnv->isa_bus, 0, MAX_ISA_SERIAL_PORTS); @@ -735,6 +735,7 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data) k->cores_mask = POWER8E_CORE_MASK; k->core_pir = pnv_chip_core_pir_p8; k->intc_create = pnv_chip_power8_intc_create; + k->isa_create = pnv_chip_power8_isa_create; k->xscom_base = 0x003fc0000000000ull; dc->desc = "PowerNV Chip POWER8E"; } @@ -749,6 +750,7 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, void *data) k->cores_mask = POWER8_CORE_MASK; k->core_pir = pnv_chip_core_pir_p8; k->intc_create = pnv_chip_power8_intc_create; + k->isa_create = pnv_chip_power8_isa_create; k->xscom_base = 0x003fc0000000000ull; dc->desc = "PowerNV Chip POWER8"; } @@ -763,6 +765,7 @@ static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data) k->cores_mask = POWER8_CORE_MASK; k->core_pir = pnv_chip_core_pir_p8; k->intc_create = pnv_chip_power8_intc_create; + k->isa_create = pnv_chip_power8nvl_isa_create; k->xscom_base = 0x003fc0000000000ull; dc->desc = "PowerNV Chip POWER8NVL"; } @@ -777,6 +780,7 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data) k->cores_mask = POWER9_CORE_MASK; k->core_pir = pnv_chip_core_pir_p9; k->intc_create = pnv_chip_power9_intc_create; + k->isa_create = pnv_chip_power9_isa_create; k->xscom_base = 0x00603fc00000000ull; dc->desc = "PowerNV Chip POWER9"; } diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c index 402c4fefa8..d7721320a2 100644 --- a/hw/ppc/pnv_lpc.c +++ b/hw/ppc/pnv_lpc.c @@ -22,6 +22,7 @@ #include "target/ppc/cpu.h" #include "qapi/error.h" #include "qemu/log.h" +#include "hw/isa/isa.h" #include "hw/ppc/pnv.h" #include "hw/ppc/pnv_lpc.h" @@ -535,16 +536,35 @@ static void pnv_lpc_isa_irq_handler(void *opaque, int n, int level) } } -qemu_irq *pnv_lpc_isa_irq_create(PnvLpcController *lpc, int chip_type, - int nirqs) +ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool use_cpld, Error **errp) { + Error *local_err = NULL; + ISABus *isa_bus; + qemu_irq *irqs; + qemu_irq_handler handler; + + /* let isa_bus_new() create its own bridge on SysBus otherwise + * devices speficied on the command line won't find the bus and + * will fail to create. + */ + isa_bus = isa_bus_new(NULL, &lpc->isa_mem, &lpc->isa_io, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return NULL; + } + /* Not all variants have a working serial irq decoder. If not, * handling of LPC interrupts becomes a platform issue (some * platforms have a CPLD to do it). */ - if (chip_type == PNV_CHIP_POWER8NVL) { - return qemu_allocate_irqs(pnv_lpc_isa_irq_handler, lpc, nirqs); + if (use_cpld) { + handler = pnv_lpc_isa_irq_handler_cpld; } else { - return qemu_allocate_irqs(pnv_lpc_isa_irq_handler_cpld, lpc, nirqs); + handler = pnv_lpc_isa_irq_handler; } + + irqs = qemu_allocate_irqs(handler, lpc, ISA_NUM_IRQS); + + isa_bus_irqs(isa_bus, irqs); + return isa_bus; } diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h index e934e84f55..563279f3e0 100644 --- a/include/hw/ppc/pnv.h +++ b/include/hw/ppc/pnv.h @@ -77,6 +77,7 @@ typedef struct PnvChipClass { uint32_t (*core_pir)(PnvChip *chip, uint32_t core_id); Object *(*intc_create)(PnvChip *chip, Object *child, Error **errp); + ISABus *(*isa_create)(PnvChip *chip, Error **errp); } PnvChipClass; #define PNV_CHIP_TYPE_SUFFIX "-" TYPE_PNV_CHIP diff --git a/include/hw/ppc/pnv_lpc.h b/include/hw/ppc/pnv_lpc.h index 53fdd5bb64..d657489b07 100644 --- a/include/hw/ppc/pnv_lpc.h +++ b/include/hw/ppc/pnv_lpc.h @@ -70,7 +70,6 @@ typedef struct PnvLpcController { PnvPsi *psi; } PnvLpcController; -qemu_irq *pnv_lpc_isa_irq_create(PnvLpcController *lpc, int chip_type, - int nirqs); +ISABus *pnv_lpc_isa_create(PnvLpcController *lpc, bool use_cpld, Error **errp); #endif /* _PPC_PNV_LPC_H */ From patchwork Fri Jun 22 04:24:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 933068 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="Lbb+A92r"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41BltZ5Tyrz9s2R for ; Fri, 22 Jun 2018 14:28:22 +1000 (AEST) Received: from localhost ([::1]:59140 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDgK-0001Z4-Bu for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 00:28:20 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39621) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDcv-0007gl-Jw for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWDcu-0003Xw-JN for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:49 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:44917) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fWDct-0003XI-Sm; Fri, 22 Jun 2018 00:24:48 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41BlpM43Dfz9s4b; Fri, 22 Jun 2018 14:24:43 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1529641483; bh=G4s6/0pBmyj4PzO/+c1w5Zz94gBQ470lhqO/C+bl3OU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Lbb+A92rlWnIZ58OlsTgcVFCeNx5Sz5O34AqxHwS1bd8RbfS8S6ikMGjTmBgqPypH HUDsg6ar+kg15qcZYuHcdrQkau6iPkWnwTfE+N74vlvOQpD7FAB8FpCTKJzv9zFWcj 3qSpcHAPeIpUuHamkvhcLFIf9K3zokAF5s/Xb5CI= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 22 Jun 2018 14:24:17 +1000 Message-Id: <20180622042437.14259-3-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180622042437.14259-1-david@gibson.dropbear.id.au> References: <20180622042437.14259-1-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 Subject: [Qemu-devel] [PATCH 03/23] spapr_cpu_core: migrate per-CPU data X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Greg Kurz A per-CPU machine data pointer was recently added to PowerPCCPU. The motivation is to to hide platform specific details from the core CPU code. This per-CPU data can hold state which is relevant to the guest though, eg, Virtual Processor Areas, and we should migrate this state. This patch adds the plumbing so that we can migrate the per-CPU data for PAPR guests. We only do this for newer machine types for the sake of backward compatibility. No state is migrated for the moment: the vmstate_spapr_cpu_state structure will be populated by subsequent patches. Signed-off-by: Greg Kurz [dwg: Fix some trivial spelling and spacing errors] Signed-off-by: David Gibson --- hw/ppc/spapr.c | 7 ++++++- hw/ppc/spapr_cpu_core.c | 22 ++++++++++++++++++++-- include/hw/ppc/spapr_cpu_core.h | 1 + 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index db0fb385d4..3174468fc5 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -4115,7 +4115,12 @@ DEFINE_SPAPR_MACHINE(3_0, "3.0", true); HW_COMPAT_2_12 \ { \ .driver = TYPE_POWERPC_CPU, \ - .property = "pre-3.0-migration", \ + .property = "pre-3.0-migration", \ + .value = "on", \ + }, \ + { \ + .driver = TYPE_SPAPR_CPU_CORE, \ + .property = "pre-3.0-migration", \ .value = "on", \ }, diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index aef3be33a3..f129ac884e 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -129,6 +129,15 @@ static void spapr_cpu_core_unrealize(DeviceState *dev, Error **errp) g_free(sc->threads); } +static const VMStateDescription vmstate_spapr_cpu_state = { + .name = "spapr_cpu", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_END_OF_LIST() + }, +}; + static void spapr_realize_vcpu(PowerPCCPU *cpu, sPAPRMachineState *spapr, Error **errp) { @@ -194,6 +203,10 @@ static PowerPCCPU *spapr_create_vcpu(sPAPRCPUCore *sc, int i, Error **errp) } cpu->machine_data = g_new0(sPAPRCPUState, 1); + if (!sc->pre_3_0_migration) { + vmstate_register(NULL, cs->cpu_index, &vmstate_spapr_cpu_state, + cpu->machine_data); + } object_unref(obj); return cpu; @@ -204,10 +217,13 @@ err: return NULL; } -static void spapr_delete_vcpu(PowerPCCPU *cpu) +static void spapr_delete_vcpu(PowerPCCPU *cpu, sPAPRCPUCore *sc) { sPAPRCPUState *spapr_cpu = spapr_cpu_state(cpu); + if (!sc->pre_3_0_migration) { + vmstate_unregister(NULL, &vmstate_spapr_cpu_state, cpu->machine_data); + } cpu->machine_data = NULL; g_free(spapr_cpu); object_unparent(OBJECT(cpu)); @@ -253,7 +269,7 @@ err_unrealize: } err: while (--i >= 0) { - spapr_delete_vcpu(sc->threads[i]); + spapr_delete_vcpu(sc->threads[i], sc); } g_free(sc->threads); error_propagate(errp, local_err); @@ -261,6 +277,8 @@ err: static Property spapr_cpu_core_properties[] = { DEFINE_PROP_INT32("node-id", sPAPRCPUCore, node_id, CPU_UNSET_NUMA_NODE_ID), + DEFINE_PROP_BOOL("pre-3.0-migration", sPAPRCPUCore, pre_3_0_migration, + false), DEFINE_PROP_END_OF_LIST() }; diff --git a/include/hw/ppc/spapr_cpu_core.h b/include/hw/ppc/spapr_cpu_core.h index 8ceea2973a..9e2821e4b3 100644 --- a/include/hw/ppc/spapr_cpu_core.h +++ b/include/hw/ppc/spapr_cpu_core.h @@ -31,6 +31,7 @@ typedef struct sPAPRCPUCore { /*< public >*/ PowerPCCPU **threads; int node_id; + bool pre_3_0_migration; /* older machine don't know about sPAPRCPUState */ } sPAPRCPUCore; typedef struct sPAPRCPUCoreClass { From patchwork Fri Jun 22 04:24:18 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 933071 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="CpkGVW+0"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41BlxQ3Kxcz9s2R for ; Fri, 22 Jun 2018 14:30:48 +1000 (AEST) Received: from localhost ([::1]:59153 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDif-0003Sd-OX for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 00:30:45 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39626) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDcw-0007gn-1l for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWDcu-0003Y3-OQ for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:50 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:45021) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fWDcu-0003XJ-0m; Fri, 22 Jun 2018 00:24:48 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41BlpM725Yz9s47; Fri, 22 Jun 2018 14:24:43 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1529641483; bh=Gttg2MbnSGMNYnufpRs11A+GBJFDm+FJgzTQ5EkIuZw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CpkGVW+0k/YGVVTHFM5f11waqMEUaX20GHO/3eHH9CAGu3+yLsDeeC6KVPaIxIMoO FRKRZq7qy4ZF5k7vakqaoU/7UzN0VzDsBA6tZuWCj3c2BaLM5rFgfHS7NuBYCDfPPF J/X9UnfiJoZ4WVS4fGtdh76g9ZysSHlHo2kKrzEw= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 22 Jun 2018 14:24:18 +1000 Message-Id: <20180622042437.14259-4-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180622042437.14259-1-david@gibson.dropbear.id.au> References: <20180622042437.14259-1-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 Subject: [Qemu-devel] [PATCH 04/23] spapr_cpu_core: migrate VPA related state X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Greg Kurz QEMU implements the "Shared Processor LPAR" (SPLPAR) option, which allows the hypervisor to time-slice a physical processor into multiple virtual processor. The intent is to allow more guests to run, and to optimize processor utilization. The guest OS can cede idle VCPUs, so that their processing capacity may be used by other VCPUs, with the H_CEDE hcall. The guest OS can also optimize spinlocks, by confering the time-slice of a spinning VCPU to the spinlock holder if it's currently notrunning, with the H_CONFER hcall. Both hcalls depend on a "Virtual Processor Area" (VPA) to be registered by the guest OS, generally during early boot. Other per-VCPU areas can be registered: the "SLB Shadow Buffer" which allows a more efficient dispatching of VCPUs, and the "Dispatch Trace Log Buffer" (DTL) which is used to compute time stolen by the hypervisor. Both DTL and SLB Shadow areas depend on the VPA to be registered. The VPA/SLB Shadow/DTL are state that QEMU should migrate, but this doesn't happen, for no apparent reason other than it was just never coded. This causes the features listed above to stop working after migration, and it breaks the logic of the H_REGISTER_VPA hcall in the destination. The VPA is set at the guest request, ie, we don't have to migrate it before the guest has actually set it. This patch hence adds an "spapr_cpu/vpa" subsection to the recently introduced per-CPU machine data migration stream. Since DTL and SLB Shadow are optional and both depend on VPA, they get their own subsections "spapr_cpu/vpa/slb_shadow" and "spapr_cpu/vpa/dtl" hanging from the "spapr_cpu/vpa" subsection. Note that this won't break migration to older QEMUs. Is is already handled by only registering the vmstate handler for per-CPU data with newer machine types. Signed-off-by: Greg Kurz Signed-off-by: David Gibson --- hw/ppc/spapr_cpu_core.c | 65 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index f129ac884e..67f1596c57 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -129,6 +129,67 @@ static void spapr_cpu_core_unrealize(DeviceState *dev, Error **errp) g_free(sc->threads); } +static bool slb_shadow_needed(void *opaque) +{ + sPAPRCPUState *spapr_cpu = opaque; + + return spapr_cpu->slb_shadow_addr != 0; +} + +static const VMStateDescription vmstate_spapr_cpu_slb_shadow = { + .name = "spapr_cpu/vpa/slb_shadow", + .version_id = 1, + .minimum_version_id = 1, + .needed = slb_shadow_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT64(slb_shadow_addr, sPAPRCPUState), + VMSTATE_UINT64(slb_shadow_size, sPAPRCPUState), + VMSTATE_END_OF_LIST() + } +}; + +static bool dtl_needed(void *opaque) +{ + sPAPRCPUState *spapr_cpu = opaque; + + return spapr_cpu->dtl_addr != 0; +} + +static const VMStateDescription vmstate_spapr_cpu_dtl = { + .name = "spapr_cpu/vpa/dtl", + .version_id = 1, + .minimum_version_id = 1, + .needed = dtl_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT64(dtl_addr, sPAPRCPUState), + VMSTATE_UINT64(dtl_size, sPAPRCPUState), + VMSTATE_END_OF_LIST() + } +}; + +static bool vpa_needed(void *opaque) +{ + sPAPRCPUState *spapr_cpu = opaque; + + return spapr_cpu->vpa_addr != 0; +} + +static const VMStateDescription vmstate_spapr_cpu_vpa = { + .name = "spapr_cpu/vpa", + .version_id = 1, + .minimum_version_id = 1, + .needed = vpa_needed, + .fields = (VMStateField[]) { + VMSTATE_UINT64(vpa_addr, sPAPRCPUState), + VMSTATE_END_OF_LIST() + }, + .subsections = (const VMStateDescription * []) { + &vmstate_spapr_cpu_slb_shadow, + &vmstate_spapr_cpu_dtl, + NULL + } +}; + static const VMStateDescription vmstate_spapr_cpu_state = { .name = "spapr_cpu", .version_id = 1, @@ -136,6 +197,10 @@ static const VMStateDescription vmstate_spapr_cpu_state = { .fields = (VMStateField[]) { VMSTATE_END_OF_LIST() }, + .subsections = (const VMStateDescription * []) { + &vmstate_spapr_cpu_vpa, + NULL + } }; static void spapr_realize_vcpu(PowerPCCPU *cpu, sPAPRMachineState *spapr, From patchwork Fri Jun 22 04:24:19 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 933094 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="L8FAE/UI"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41BmDn3G02z9s0W for ; Fri, 22 Jun 2018 14:44:09 +1000 (AEST) Received: from localhost ([::1]:59232 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDvb-0004T8-61 for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 00:44:07 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39762) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDd1-0007lJ-6F for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWDcx-0003ZM-9r for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:55 -0400 Received: from ozlabs.org ([203.11.71.1]:60833) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fWDcw-0003Y7-Kj; Fri, 22 Jun 2018 00:24:51 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41BlpN0WQpz9s5c; Fri, 22 Jun 2018 14:24:43 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1529641484; bh=Vj+6KoJN8gmNUNdKU6UBo4ASajGvwdtIBnQ2EQBsKCg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=L8FAE/UIQ62FANr+RSnC8gQU4KquFvW2148AXxAWoJggQtqe9L6VLwURVci0be98t i9F4Rkpr87Apily+qlUcD48Hqtm1f5fFzXqvKQ2VNibLKbumgZHctE4qNNf75f+u/E d0qhNlZlI5HghXz41C6wcpVcAaQgxddsoOdOQG3A= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 22 Jun 2018 14:24:19 +1000 Message-Id: <20180622042437.14259-5-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180622042437.14259-1-david@gibson.dropbear.id.au> References: <20180622042437.14259-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PATCH 05/23] ppc/pnv: introduce Pnv8Chip and Pnv9Chip models X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Cédric Le Goater It introduces a base PnvChip class from which the specific processor chip classes, Pnv8Chip and Pnv9Chip, inherit. Each of them needs to define an init and a realize routine which will create the controllers of the target processor. For the moment, the base PnvChip class handles the XSCOM bus and the cores. Signed-off-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/ppc/pnv.c | 281 +++++++++++++++++++++++++++---------------- include/hw/ppc/pnv.h | 24 +++- 2 files changed, 202 insertions(+), 103 deletions(-) diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index ac828d1331..a29ea996b4 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -531,12 +531,14 @@ static void pnv_reset(void) static ISABus *pnv_chip_power8_isa_create(PnvChip *chip, Error **errp) { - return pnv_lpc_isa_create(&chip->lpc, true, errp); + Pnv8Chip *chip8 = PNV8_CHIP(chip); + return pnv_lpc_isa_create(&chip8->lpc, true, errp); } static ISABus *pnv_chip_power8nvl_isa_create(PnvChip *chip, Error **errp) { - return pnv_lpc_isa_create(&chip->lpc, false, errp); + Pnv8Chip *chip8 = PNV8_CHIP(chip); + return pnv_lpc_isa_create(&chip8->lpc, false, errp); } static ISABus *pnv_chip_power9_isa_create(PnvChip *chip, Error **errp) @@ -725,6 +727,103 @@ static Object *pnv_chip_power9_intc_create(PnvChip *chip, Object *child, */ #define POWER9_CORE_MASK (0xffffffffffffffull) +static void pnv_chip_power8_instance_init(Object *obj) +{ + Pnv8Chip *chip8 = PNV8_CHIP(obj); + + object_initialize(&chip8->psi, sizeof(chip8->psi), TYPE_PNV_PSI); + object_property_add_child(obj, "psi", OBJECT(&chip8->psi), NULL); + object_property_add_const_link(OBJECT(&chip8->psi), "xics", + OBJECT(qdev_get_machine()), &error_abort); + + object_initialize(&chip8->lpc, sizeof(chip8->lpc), TYPE_PNV_LPC); + object_property_add_child(obj, "lpc", OBJECT(&chip8->lpc), NULL); + object_property_add_const_link(OBJECT(&chip8->lpc), "psi", + OBJECT(&chip8->psi), &error_abort); + + object_initialize(&chip8->occ, sizeof(chip8->occ), TYPE_PNV_OCC); + object_property_add_child(obj, "occ", OBJECT(&chip8->occ), NULL); + object_property_add_const_link(OBJECT(&chip8->occ), "psi", + OBJECT(&chip8->psi), &error_abort); +} + +static void pnv_chip_icp_realize(Pnv8Chip *chip8, Error **errp) + { + PnvChip *chip = PNV_CHIP(chip8); + PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip); + const char *typename = pnv_chip_core_typename(chip); + size_t typesize = object_type_get_instance_size(typename); + int i, j; + char *name; + XICSFabric *xi = XICS_FABRIC(qdev_get_machine()); + + name = g_strdup_printf("icp-%x", chip->chip_id); + memory_region_init(&chip8->icp_mmio, OBJECT(chip), name, PNV_ICP_SIZE); + sysbus_init_mmio(SYS_BUS_DEVICE(chip), &chip8->icp_mmio); + g_free(name); + + sysbus_mmio_map(SYS_BUS_DEVICE(chip), 1, PNV_ICP_BASE(chip)); + + /* Map the ICP registers for each thread */ + for (i = 0; i < chip->nr_cores; i++) { + PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize); + int core_hwid = CPU_CORE(pnv_core)->core_id; + + for (j = 0; j < CPU_CORE(pnv_core)->nr_threads; j++) { + uint32_t pir = pcc->core_pir(chip, core_hwid) + j; + PnvICPState *icp = PNV_ICP(xics_icp_get(xi, pir)); + + memory_region_add_subregion(&chip8->icp_mmio, pir << 12, + &icp->mmio); + } + } +} + +static void pnv_chip_power8_realize(DeviceState *dev, Error **errp) +{ + PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev); + PnvChip *chip = PNV_CHIP(dev); + Pnv8Chip *chip8 = PNV8_CHIP(dev); + Error *local_err = NULL; + + pcc->parent_realize(dev, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + /* Processor Service Interface (PSI) Host Bridge */ + object_property_set_int(OBJECT(&chip8->psi), PNV_PSIHB_BASE(chip), + "bar", &error_fatal); + object_property_set_bool(OBJECT(&chip8->psi), true, "realized", &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + pnv_xscom_add_subregion(chip, PNV_XSCOM_PSIHB_BASE, &chip8->psi.xscom_regs); + + /* Create LPC controller */ + object_property_set_bool(OBJECT(&chip8->lpc), true, "realized", + &error_fatal); + pnv_xscom_add_subregion(chip, PNV_XSCOM_LPC_BASE, &chip8->lpc.xscom_regs); + + /* Interrupt Management Area. This is the memory region holding + * all the Interrupt Control Presenter (ICP) registers */ + pnv_chip_icp_realize(chip8, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + /* Create the simplified OCC model */ + object_property_set_bool(OBJECT(&chip8->occ), true, "realized", &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + pnv_xscom_add_subregion(chip, PNV_XSCOM_OCC_BASE, &chip8->occ.xscom_regs); +} + static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -738,6 +837,9 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data) k->isa_create = pnv_chip_power8_isa_create; k->xscom_base = 0x003fc0000000000ull; dc->desc = "PowerNV Chip POWER8E"; + + device_class_set_parent_realize(dc, pnv_chip_power8_realize, + &k->parent_realize); } static void pnv_chip_power8_class_init(ObjectClass *klass, void *data) @@ -753,6 +855,9 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, void *data) k->isa_create = pnv_chip_power8_isa_create; k->xscom_base = 0x003fc0000000000ull; dc->desc = "PowerNV Chip POWER8"; + + device_class_set_parent_realize(dc, pnv_chip_power8_realize, + &k->parent_realize); } static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data) @@ -768,6 +873,25 @@ static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data) k->isa_create = pnv_chip_power8nvl_isa_create; k->xscom_base = 0x003fc0000000000ull; dc->desc = "PowerNV Chip POWER8NVL"; + + device_class_set_parent_realize(dc, pnv_chip_power8_realize, + &k->parent_realize); +} + +static void pnv_chip_power9_instance_init(Object *obj) +{ +} + +static void pnv_chip_power9_realize(DeviceState *dev, Error **errp) +{ + PnvChipClass *pcc = PNV_CHIP_GET_CLASS(dev); + Error *local_err = NULL; + + pcc->parent_realize(dev, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } } static void pnv_chip_power9_class_init(ObjectClass *klass, void *data) @@ -783,6 +907,9 @@ static void pnv_chip_power9_class_init(ObjectClass *klass, void *data) k->isa_create = pnv_chip_power9_isa_create; k->xscom_base = 0x00603fc00000000ull; dc->desc = "PowerNV Chip POWER9"; + + device_class_set_parent_realize(dc, pnv_chip_power9_realize, + &k->parent_realize); } static void pnv_chip_core_sanitize(PnvChip *chip, Error **errp) @@ -815,59 +942,9 @@ static void pnv_chip_core_sanitize(PnvChip *chip, Error **errp) } } -static void pnv_chip_init(Object *obj) +static void pnv_chip_instance_init(Object *obj) { - PnvChip *chip = PNV_CHIP(obj); - PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip); - - chip->xscom_base = pcc->xscom_base; - - object_initialize(&chip->lpc, sizeof(chip->lpc), TYPE_PNV_LPC); - object_property_add_child(obj, "lpc", OBJECT(&chip->lpc), NULL); - - object_initialize(&chip->psi, sizeof(chip->psi), TYPE_PNV_PSI); - object_property_add_child(obj, "psi", OBJECT(&chip->psi), NULL); - object_property_add_const_link(OBJECT(&chip->psi), "xics", - OBJECT(qdev_get_machine()), &error_abort); - - object_initialize(&chip->occ, sizeof(chip->occ), TYPE_PNV_OCC); - object_property_add_child(obj, "occ", OBJECT(&chip->occ), NULL); - object_property_add_const_link(OBJECT(&chip->occ), "psi", - OBJECT(&chip->psi), &error_abort); - - /* The LPC controller needs PSI to generate interrupts */ - object_property_add_const_link(OBJECT(&chip->lpc), "psi", - OBJECT(&chip->psi), &error_abort); -} - -static void pnv_chip_icp_realize(PnvChip *chip, Error **errp) -{ - PnvChipClass *pcc = PNV_CHIP_GET_CLASS(chip); - const char *typename = pnv_chip_core_typename(chip); - size_t typesize = object_type_get_instance_size(typename); - int i, j; - char *name; - XICSFabric *xi = XICS_FABRIC(qdev_get_machine()); - - name = g_strdup_printf("icp-%x", chip->chip_id); - memory_region_init(&chip->icp_mmio, OBJECT(chip), name, PNV_ICP_SIZE); - sysbus_init_mmio(SYS_BUS_DEVICE(chip), &chip->icp_mmio); - g_free(name); - - sysbus_mmio_map(SYS_BUS_DEVICE(chip), 1, PNV_ICP_BASE(chip)); - - /* Map the ICP registers for each thread */ - for (i = 0; i < chip->nr_cores; i++) { - PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize); - int core_hwid = CPU_CORE(pnv_core)->core_id; - - for (j = 0; j < CPU_CORE(pnv_core)->nr_threads; j++) { - uint32_t pir = pcc->core_pir(chip, core_hwid) + j; - PnvICPState *icp = PNV_ICP(xics_icp_get(xi, pir)); - - memory_region_add_subregion(&chip->icp_mmio, pir << 12, &icp->mmio); - } - } + PNV_CHIP(obj)->xscom_base = PNV_CHIP_GET_CLASS(obj)->xscom_base; } static void pnv_chip_core_realize(PnvChip *chip, Error **errp) @@ -951,37 +1028,6 @@ static void pnv_chip_realize(DeviceState *dev, Error **errp) error_propagate(errp, error); return; } - - /* Create LPC controller */ - object_property_set_bool(OBJECT(&chip->lpc), true, "realized", - &error_fatal); - pnv_xscom_add_subregion(chip, PNV_XSCOM_LPC_BASE, &chip->lpc.xscom_regs); - - /* Interrupt Management Area. This is the memory region holding - * all the Interrupt Control Presenter (ICP) registers */ - pnv_chip_icp_realize(chip, &error); - if (error) { - error_propagate(errp, error); - return; - } - - /* Processor Service Interface (PSI) Host Bridge */ - object_property_set_int(OBJECT(&chip->psi), PNV_PSIHB_BASE(chip), - "bar", &error_fatal); - object_property_set_bool(OBJECT(&chip->psi), true, "realized", &error); - if (error) { - error_propagate(errp, error); - return; - } - pnv_xscom_add_subregion(chip, PNV_XSCOM_PSIHB_BASE, &chip->psi.xscom_regs); - - /* Create the simplified OCC model */ - object_property_set_bool(OBJECT(&chip->occ), true, "realized", &error); - if (error) { - error_propagate(errp, error); - return; - } - pnv_xscom_add_subregion(chip, PNV_XSCOM_OCC_BASE, &chip->occ.xscom_regs); } static Property pnv_chip_properties[] = { @@ -1009,8 +1055,10 @@ static ICSState *pnv_ics_get(XICSFabric *xi, int irq) int i; for (i = 0; i < pnv->num_chips; i++) { - if (ics_valid_irq(&pnv->chips[i]->psi.ics, irq)) { - return &pnv->chips[i]->psi.ics; + Pnv8Chip *chip8 = PNV8_CHIP(pnv->chips[i]); + + if (ics_valid_irq(&chip8->psi.ics, irq)) { + return &chip8->psi.ics; } } return NULL; @@ -1022,7 +1070,8 @@ static void pnv_ics_resend(XICSFabric *xi) int i; for (i = 0; i < pnv->num_chips; i++) { - ics_resend(&pnv->chips[i]->psi.ics); + Pnv8Chip *chip8 = PNV8_CHIP(pnv->chips[i]); + ics_resend(&chip8->psi.ics); } } @@ -1063,7 +1112,8 @@ static void pnv_pic_print_info(InterruptStatsProvider *obj, } for (i = 0; i < pnv->num_chips; i++) { - ics_pic_print_info(&pnv->chips[i]->psi.ics, mon); + Pnv8Chip *chip8 = PNV8_CHIP(pnv->chips[i]); + ics_pic_print_info(&chip8->psi.ics, mon); } } @@ -1098,7 +1148,7 @@ static void pnv_set_num_chips(Object *obj, Visitor *v, const char *name, pnv->num_chips = num_chips; } -static void pnv_machine_initfn(Object *obj) +static void pnv_machine_instance_init(Object *obj) { PnvMachineState *pnv = PNV_MACHINE(obj); pnv->num_chips = 1; @@ -1138,11 +1188,18 @@ static void pnv_machine_class_init(ObjectClass *oc, void *data) pnv_machine_class_props_init(oc); } -#define DEFINE_PNV_CHIP_TYPE(type, class_initfn) \ - { \ - .name = type, \ - .class_init = class_initfn, \ - .parent = TYPE_PNV_CHIP, \ +#define DEFINE_PNV8_CHIP_TYPE(type, class_initfn) \ + { \ + .name = type, \ + .class_init = class_initfn, \ + .parent = TYPE_PNV8_CHIP, \ + } + +#define DEFINE_PNV9_CHIP_TYPE(type, class_initfn) \ + { \ + .name = type, \ + .class_init = class_initfn, \ + .parent = TYPE_PNV9_CHIP, \ } static const TypeInfo types[] = { @@ -1150,7 +1207,7 @@ static const TypeInfo types[] = { .name = TYPE_PNV_MACHINE, .parent = TYPE_MACHINE, .instance_size = sizeof(PnvMachineState), - .instance_init = pnv_machine_initfn, + .instance_init = pnv_machine_instance_init, .class_init = pnv_machine_class_init, .interfaces = (InterfaceInfo[]) { { TYPE_XICS_FABRIC }, @@ -1162,16 +1219,36 @@ static const TypeInfo types[] = { .name = TYPE_PNV_CHIP, .parent = TYPE_SYS_BUS_DEVICE, .class_init = pnv_chip_class_init, - .instance_init = pnv_chip_init, + .instance_init = pnv_chip_instance_init, .instance_size = sizeof(PnvChip), .class_size = sizeof(PnvChipClass), .abstract = true, }, - DEFINE_PNV_CHIP_TYPE(TYPE_PNV_CHIP_POWER9, pnv_chip_power9_class_init), - DEFINE_PNV_CHIP_TYPE(TYPE_PNV_CHIP_POWER8, pnv_chip_power8_class_init), - DEFINE_PNV_CHIP_TYPE(TYPE_PNV_CHIP_POWER8E, pnv_chip_power8e_class_init), - DEFINE_PNV_CHIP_TYPE(TYPE_PNV_CHIP_POWER8NVL, - pnv_chip_power8nvl_class_init), + + /* + * P9 chip and variants + */ + { + .name = TYPE_PNV9_CHIP, + .parent = TYPE_PNV_CHIP, + .instance_init = pnv_chip_power9_instance_init, + .instance_size = sizeof(Pnv9Chip), + }, + DEFINE_PNV9_CHIP_TYPE(TYPE_PNV_CHIP_POWER9, pnv_chip_power9_class_init), + + /* + * P8 chip and variants + */ + { + .name = TYPE_PNV8_CHIP, + .parent = TYPE_PNV_CHIP, + .instance_init = pnv_chip_power8_instance_init, + .instance_size = sizeof(Pnv8Chip), + }, + DEFINE_PNV8_CHIP_TYPE(TYPE_PNV_CHIP_POWER8, pnv_chip_power8_class_init), + DEFINE_PNV8_CHIP_TYPE(TYPE_PNV_CHIP_POWER8E, pnv_chip_power8e_class_init), + DEFINE_PNV8_CHIP_TYPE(TYPE_PNV_CHIP_POWER8NVL, + pnv_chip_power8nvl_class_init), }; DEFINE_TYPES(types) diff --git a/include/hw/ppc/pnv.h b/include/hw/ppc/pnv.h index 563279f3e0..86d5f54e54 100644 --- a/include/hw/ppc/pnv.h +++ b/include/hw/ppc/pnv.h @@ -57,12 +57,32 @@ typedef struct PnvChip { MemoryRegion xscom_mmio; MemoryRegion xscom; AddressSpace xscom_as; +} PnvChip; + +#define TYPE_PNV8_CHIP "pnv8-chip" +#define PNV8_CHIP(obj) OBJECT_CHECK(Pnv8Chip, (obj), TYPE_PNV8_CHIP) + +typedef struct Pnv8Chip { + /*< private >*/ + PnvChip parent_obj; + + /*< public >*/ MemoryRegion icp_mmio; PnvLpcController lpc; PnvPsi psi; PnvOCC occ; -} PnvChip; +} Pnv8Chip; + +#define TYPE_PNV9_CHIP "pnv9-chip" +#define PNV9_CHIP(obj) OBJECT_CHECK(Pnv9Chip, (obj), TYPE_PNV9_CHIP) + +typedef struct Pnv9Chip { + /*< private >*/ + PnvChip parent_obj; + + /*< public >*/ +} Pnv9Chip; typedef struct PnvChipClass { /*< private >*/ @@ -75,6 +95,8 @@ typedef struct PnvChipClass { hwaddr xscom_base; + DeviceRealize parent_realize; + uint32_t (*core_pir)(PnvChip *chip, uint32_t core_id); Object *(*intc_create)(PnvChip *chip, Object *child, Error **errp); ISABus *(*isa_create)(PnvChip *chip, Error **errp); From patchwork Fri Jun 22 04:24:20 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 933065 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="Td/Rgew1"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41BlqM0NXhz9s47 for ; Fri, 22 Jun 2018 14:25:35 +1000 (AEST) Received: from localhost ([::1]:59119 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDdc-0007h6-JG for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 00:25:32 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39616) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDcv-0007gf-Gl for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:50 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWDcu-0003Xq-Eu for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:49 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:60255) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fWDct-0003XH-Pd; Fri, 22 Jun 2018 00:24:48 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41BlpM6R5cz9s4v; Fri, 22 Jun 2018 14:24:43 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1529641483; bh=tluKWJuSjMbLo1HJFwzFbeJ4BhUiUGs87QTdYAhlYYU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Td/Rgew1334hJbdXUq2lGA1LNIC1cre/9+WfJIlGQ8RpGpeF9Qi1Th7gIaBjjO3eC Rzg5ubq0icBcW09xzV0U4YHq1SIvHkulPYmFAXZjZFTEAGae8Kga1KMje34XG23FdT 5vEfNONyFSCHqYbp9YQKI2dGry2rWXmP1yDC+4eQ= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 22 Jun 2018 14:24:20 +1000 Message-Id: <20180622042437.14259-6-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180622042437.14259-1-david@gibson.dropbear.id.au> References: <20180622042437.14259-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 Subject: [Qemu-devel] [PATCH 06/23] ppc/pnv: consolidate the creation of the ISA bus device tree X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Cédric Le Goater The device tree node of the ISA bus was being partially done in different places. Move all the nodes creation under the same routine. Signed-off-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/ppc/pnv.c | 51 +++++++++++++++++++++++---------------------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index a29ea996b4..7401ffe5b0 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -265,18 +265,6 @@ static void pnv_dt_icp(PnvChip *chip, void *fdt, uint32_t pir, g_free(reg); } -static int pnv_chip_lpc_offset(PnvChip *chip, void *fdt) -{ - char *name; - int offset; - - name = g_strdup_printf("/xscom@%" PRIx64 "/isa@%x", - (uint64_t) PNV_XSCOM_BASE(chip), PNV_XSCOM_LPC_BASE); - offset = fdt_path_offset(fdt, name); - g_free(name); - return offset; -} - static void pnv_dt_chip(PnvChip *chip, void *fdt) { const char *typename = pnv_chip_core_typename(chip); @@ -285,16 +273,6 @@ static void pnv_dt_chip(PnvChip *chip, void *fdt) pnv_dt_xscom(chip, fdt, 0); - /* The default LPC bus of a multichip system is on chip 0. It's - * recognized by the firmware (skiboot) using a "primary" - * property. - */ - if (chip->chip_id == 0x0) { - int lpc_offset = pnv_chip_lpc_offset(chip, fdt); - - _FDT((fdt_setprop(fdt, lpc_offset, "primary", NULL, 0))); - } - for (i = 0; i < chip->nr_cores; i++) { PnvCore *pnv_core = PNV_CORE(chip->cores + i * typesize); @@ -418,16 +396,35 @@ static int pnv_dt_isa_device(DeviceState *dev, void *opaque) return 0; } -static void pnv_dt_isa(ISABus *bus, void *fdt, int lpc_offset) +static int pnv_chip_isa_offset(PnvChip *chip, void *fdt) +{ + char *name; + int offset; + + name = g_strdup_printf("/xscom@%" PRIx64 "/isa@%x", + (uint64_t) PNV_XSCOM_BASE(chip), PNV_XSCOM_LPC_BASE); + offset = fdt_path_offset(fdt, name); + g_free(name); + return offset; +} + +/* The default LPC bus of a multichip system is on chip 0. It's + * recognized by the firmware (skiboot) using a "primary" property. + */ +static void pnv_dt_isa(PnvMachineState *pnv, void *fdt) { + int isa_offset = pnv_chip_isa_offset(pnv->chips[0], fdt); ForeachPopulateArgs args = { .fdt = fdt, - .offset = lpc_offset, + .offset = isa_offset, }; + _FDT((fdt_setprop(fdt, isa_offset, "primary", NULL, 0))); + /* ISA devices are not necessarily parented to the ISA bus so we * can not use object_child_foreach() */ - qbus_walk_children(BUS(bus), pnv_dt_isa_device, NULL, NULL, NULL, &args); + qbus_walk_children(BUS(pnv->isa_bus), pnv_dt_isa_device, NULL, NULL, NULL, + &args); } static void *pnv_dt_create(MachineState *machine) @@ -438,7 +435,6 @@ static void *pnv_dt_create(MachineState *machine) char *buf; int off; int i; - int lpc_offset; fdt = g_malloc0(FDT_MAX_SIZE); _FDT((fdt_create_empty_tree(fdt, FDT_MAX_SIZE))); @@ -480,8 +476,7 @@ static void *pnv_dt_create(MachineState *machine) } /* Populate ISA devices on chip 0 */ - lpc_offset = pnv_chip_lpc_offset(pnv->chips[0], fdt); - pnv_dt_isa(pnv->isa_bus, fdt, lpc_offset); + pnv_dt_isa(pnv, fdt); if (pnv->bmc) { pnv_dt_bmc_sensors(pnv->bmc, fdt); From patchwork Fri Jun 22 04:24:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 933073 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="pRZqQALY"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Blxt4Phxz9s2R for ; Fri, 22 Jun 2018 14:31:14 +1000 (AEST) Received: from localhost ([::1]:59159 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDj6-0003lS-5t for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 00:31:12 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39758) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDd1-0007l5-15 for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWDcx-0003ZR-AU for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:55 -0400 Received: from ozlabs.org ([203.11.71.1]:38155) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fWDcw-0003Y8-MG; Fri, 22 Jun 2018 00:24:51 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41BlpN16M4z9s70; Fri, 22 Jun 2018 14:24:43 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1529641484; bh=98AL0gJyosMz84B0LuXMzkBnihdwnvkM7gjZTZztqfo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=pRZqQALYxCH2yNI2PIqefxuzDJBSJIBK+MZJb+TYHEbXwNkwgC+ilemL+TEB4kQKu 03JvjNqzNBp1GawMrbVL4m6FfBSCfpHCqnIhXh1mgP2z6mG+90hSVV7c4CtvN3Ronh lraxZ/5u3befXlTsJfA29D03SgeuhppR4mefqG+E= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 22 Jun 2018 14:24:21 +1000 Message-Id: <20180622042437.14259-7-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180622042437.14259-1-david@gibson.dropbear.id.au> References: <20180622042437.14259-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PATCH 07/23] target/ppc: Allow cpu compatiblity checks based on type, not instance X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" ppc_check_compat() is used in a number of places to check if a cpu object supports a certain compatiblity mode, subject to various constraints. It takes a PowerPCCPU *, however it really only depends on the cpu's class. We have upcoming cases where it would be useful to make compatibility checks before we fully instantiate the cpu objects. ppc_type_check_compat() will now make an equivalent check, but based on a CPU's QOM typename instead of an instantiated CPU object. We make use of the new interface in several places in spapr, where we're essentially making a global check, rather than one specific to a particular cpu. This avoids some ugly uses of first_cpu to grab a "representative" instance. Signed-off-by: David Gibson Reviewed-by: Greg Kurz Reviewed-by: Cédric Le Goater --- hw/ppc/spapr.c | 10 ++++------ hw/ppc/spapr_caps.c | 19 +++++++++---------- target/ppc/compat.c | 27 +++++++++++++++++++++------ target/ppc/cpu.h | 4 ++++ 4 files changed, 38 insertions(+), 22 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 3174468fc5..bc179f6f89 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1616,8 +1616,8 @@ static void spapr_machine_reset(void) first_ppc_cpu = POWERPC_CPU(first_cpu); if (kvm_enabled() && kvmppc_has_cap_mmu_radix() && - ppc_check_compat(first_ppc_cpu, CPU_POWERPC_LOGICAL_3_00, 0, - spapr->max_compat_pvr)) { + ppc_type_check_compat(machine->cpu_type, CPU_POWERPC_LOGICAL_3_00, 0, + spapr->max_compat_pvr)) { /* If using KVM with radix mode available, VCPUs can be started * without a HPT because KVM will start them in radix mode. * Set the GR bit in PATB so that we know there is no HPT. */ @@ -2520,7 +2520,6 @@ static void spapr_machine_init(MachineState *machine) long load_limit, fw_size; char *filename; Error *resize_hpt_err = NULL; - PowerPCCPU *first_ppc_cpu; msi_nonbroken = true; @@ -2618,10 +2617,9 @@ static void spapr_machine_init(MachineState *machine) /* init CPUs */ spapr_init_cpus(spapr); - first_ppc_cpu = POWERPC_CPU(first_cpu); if ((!kvm_enabled() || kvmppc_has_cap_mmu_radix()) && - ppc_check_compat(first_ppc_cpu, CPU_POWERPC_LOGICAL_3_00, 0, - spapr->max_compat_pvr)) { + ppc_type_check_compat(machine->cpu_type, CPU_POWERPC_LOGICAL_3_00, 0, + spapr->max_compat_pvr)) { /* KVM and TCG always allow GTSE with radix... */ spapr_ovec_set(spapr->ov5, OV5_MMU_RADIX_GTSE); } diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c index 00e43a9ba7..469f38f0ef 100644 --- a/hw/ppc/spapr_caps.c +++ b/hw/ppc/spapr_caps.c @@ -327,27 +327,26 @@ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = { }; static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr, - CPUState *cs) + const char *cputype) { sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); - PowerPCCPU *cpu = POWERPC_CPU(cs); sPAPRCapabilities caps; caps = smc->default_caps; - if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_07, - 0, spapr->max_compat_pvr)) { + if (!ppc_type_check_compat(cputype, CPU_POWERPC_LOGICAL_2_07, + 0, spapr->max_compat_pvr)) { caps.caps[SPAPR_CAP_HTM] = SPAPR_CAP_OFF; caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN; } - if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_06_PLUS, - 0, spapr->max_compat_pvr)) { + if (!ppc_type_check_compat(cputype, CPU_POWERPC_LOGICAL_2_06_PLUS, + 0, spapr->max_compat_pvr)) { caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN; } - if (!ppc_check_compat(cpu, CPU_POWERPC_LOGICAL_2_06, - 0, spapr->max_compat_pvr)) { + if (!ppc_type_check_compat(cputype, CPU_POWERPC_LOGICAL_2_06, + 0, spapr->max_compat_pvr)) { caps.caps[SPAPR_CAP_VSX] = SPAPR_CAP_OFF; caps.caps[SPAPR_CAP_DFP] = SPAPR_CAP_OFF; caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN; @@ -384,7 +383,7 @@ int spapr_caps_post_migration(sPAPRMachineState *spapr) sPAPRCapabilities dstcaps = spapr->eff; sPAPRCapabilities srccaps; - srccaps = default_caps_with_cpu(spapr, first_cpu); + srccaps = default_caps_with_cpu(spapr, MACHINE(spapr)->cpu_type); for (i = 0; i < SPAPR_CAP_NUM; i++) { /* If not default value then assume came in with the migration */ if (spapr->mig.caps[i] != spapr->def.caps[i]) { @@ -446,7 +445,7 @@ void spapr_caps_reset(sPAPRMachineState *spapr) int i; /* First compute the actual set of caps we're running with.. */ - default_caps = default_caps_with_cpu(spapr, first_cpu); + default_caps = default_caps_with_cpu(spapr, MACHINE(spapr)->cpu_type); for (i = 0; i < SPAPR_CAP_NUM; i++) { /* Store the defaults */ diff --git a/target/ppc/compat.c b/target/ppc/compat.c index 807c906f68..7de4bf3122 100644 --- a/target/ppc/compat.c +++ b/target/ppc/compat.c @@ -105,17 +105,13 @@ static const CompatInfo *compat_by_pvr(uint32_t pvr) return NULL; } -bool ppc_check_compat(PowerPCCPU *cpu, uint32_t compat_pvr, - uint32_t min_compat_pvr, uint32_t max_compat_pvr) +static bool pcc_compat(PowerPCCPUClass *pcc, uint32_t compat_pvr, + uint32_t min_compat_pvr, uint32_t max_compat_pvr) { - PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); const CompatInfo *compat = compat_by_pvr(compat_pvr); const CompatInfo *min = compat_by_pvr(min_compat_pvr); const CompatInfo *max = compat_by_pvr(max_compat_pvr); -#if !defined(CONFIG_USER_ONLY) - g_assert(cpu->vhyp); -#endif g_assert(!min_compat_pvr || min); g_assert(!max_compat_pvr || max); @@ -134,6 +130,25 @@ bool ppc_check_compat(PowerPCCPU *cpu, uint32_t compat_pvr, return true; } +bool ppc_check_compat(PowerPCCPU *cpu, uint32_t compat_pvr, + uint32_t min_compat_pvr, uint32_t max_compat_pvr) +{ + PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); + +#if !defined(CONFIG_USER_ONLY) + g_assert(cpu->vhyp); +#endif + + return pcc_compat(pcc, compat_pvr, min_compat_pvr, max_compat_pvr); +} + +bool ppc_type_check_compat(const char *cputype, uint32_t compat_pvr, + uint32_t min_compat_pvr, uint32_t max_compat_pvr) +{ + PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(object_class_by_name(cputype)); + return pcc_compat(pcc, compat_pvr, min_compat_pvr, max_compat_pvr); +} + void ppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr, Error **errp) { const CompatInfo *compat = compat_by_pvr(compat_pvr); diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 874da6efbc..c7f3fb6b73 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -1369,7 +1369,11 @@ static inline int cpu_mmu_index (CPUPPCState *env, bool ifetch) #if defined(TARGET_PPC64) bool ppc_check_compat(PowerPCCPU *cpu, uint32_t compat_pvr, uint32_t min_compat_pvr, uint32_t max_compat_pvr); +bool ppc_type_check_compat(const char *cputype, uint32_t compat_pvr, + uint32_t min_compat_pvr, uint32_t max_compat_pvr); + void ppc_set_compat(PowerPCCPU *cpu, uint32_t compat_pvr, Error **errp); + #if !defined(CONFIG_USER_ONLY) void ppc_set_compat_all(uint32_t compat_pvr, Error **errp); #endif From patchwork Fri Jun 22 04:24:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 933080 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="CZJoKFH/"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Bm114g3bz9s2R for ; Fri, 22 Jun 2018 14:33:57 +1000 (AEST) Received: from localhost ([::1]:59169 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDlj-0005b7-98 for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 00:33:55 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39734) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDd0-0007jL-B1 for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWDcy-0003aL-0q for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:54 -0400 Received: from ozlabs.org ([203.11.71.1]:52169) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fWDcx-0003YR-9i; Fri, 22 Jun 2018 00:24:51 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41BlpN6VGGz9s7T; Fri, 22 Jun 2018 14:24:43 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1529641484; bh=5kVo7kuy6Crpk2lviDJ0KahBmkaoHUO8wc6doWkIOAY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CZJoKFH/O+AfhEPmXXU2a2n/SF7m0otcSvp0PPfYBqmQA5r+GnVTDhzHFjh9XsDCm gtaHsAjYYqNwlAR2SDeSi3h80ZQVbUL+kCesALOBeqR/P8LAtnVyshUHPuaXy6T7Rp u/4QdET6sM8Z7NVG1qEKwv9MIpSgdQarfyKTnGZg= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 22 Jun 2018 14:24:22 +1000 Message-Id: <20180622042437.14259-8-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180622042437.14259-1-david@gibson.dropbear.id.au> References: <20180622042437.14259-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PATCH 08/23] spapr: Compute effective capability values earlier X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Previously, the effective values of the various spapr capability flags were only determined at machine reset time. That was a lazy way of making sure it was after cpu initialization so it could use the cpu object to inform the defaults. But we've now improved the compat checking code so that we don't need to instantiate the cpus to use it. That lets us move the resolution of the capability defaults much earlier. This is going to be necessary for some future capabilities. Signed-off-by: David Gibson Reviewed-by: Greg Kurz Reviewed-by: Cédric Le Goater --- hw/ppc/spapr.c | 6 ++++-- hw/ppc/spapr_caps.c | 9 ++++++--- include/hw/ppc/spapr.h | 3 ++- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index bc179f6f89..4a0b679166 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -1612,7 +1612,7 @@ static void spapr_machine_reset(void) void *fdt; int rc; - spapr_caps_reset(spapr); + spapr_caps_apply(spapr); first_ppc_cpu = POWERPC_CPU(first_cpu); if (kvm_enabled() && kvmppc_has_cap_mmu_radix() && @@ -2526,7 +2526,9 @@ static void spapr_machine_init(MachineState *machine) QLIST_INIT(&spapr->phbs); QTAILQ_INIT(&spapr->pending_dimm_unplugs); - /* Check HPT resizing availability */ + /* Determine capabilities to run with */ + spapr_caps_init(spapr); + kvmppc_check_papr_resize_hpt(&resize_hpt_err); if (spapr->resize_hpt == SPAPR_RESIZE_HPT_DEFAULT) { /* diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c index 469f38f0ef..dabed817d1 100644 --- a/hw/ppc/spapr_caps.c +++ b/hw/ppc/spapr_caps.c @@ -439,12 +439,12 @@ SPAPR_CAP_MIG_STATE(cfpc, SPAPR_CAP_CFPC); SPAPR_CAP_MIG_STATE(sbbc, SPAPR_CAP_SBBC); SPAPR_CAP_MIG_STATE(ibs, SPAPR_CAP_IBS); -void spapr_caps_reset(sPAPRMachineState *spapr) +void spapr_caps_init(sPAPRMachineState *spapr) { sPAPRCapabilities default_caps; int i; - /* First compute the actual set of caps we're running with.. */ + /* Compute the actual set of caps we should run with */ default_caps = default_caps_with_cpu(spapr, MACHINE(spapr)->cpu_type); for (i = 0; i < SPAPR_CAP_NUM; i++) { @@ -455,8 +455,11 @@ void spapr_caps_reset(sPAPRMachineState *spapr) spapr->eff.caps[i] = default_caps.caps[i]; } } +} - /* .. then apply those caps to the virtual hardware */ +void spapr_caps_apply(sPAPRMachineState *spapr) +{ + int i; for (i = 0; i < SPAPR_CAP_NUM; i++) { sPAPRCapabilityInfo *info = &capability_table[i]; diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 3388750fc7..9dbd6010f5 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -798,7 +798,8 @@ static inline uint8_t spapr_get_cap(sPAPRMachineState *spapr, int cap) return spapr->eff.caps[cap]; } -void spapr_caps_reset(sPAPRMachineState *spapr); +void spapr_caps_init(sPAPRMachineState *spapr); +void spapr_caps_apply(sPAPRMachineState *spapr); void spapr_caps_add_properties(sPAPRMachineClass *smc, Error **errp); int spapr_caps_post_migration(sPAPRMachineState *spapr); From patchwork Fri Jun 22 04:24:23 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 933081 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="mHYd21ex"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Bm131cJ7z9s2R for ; Fri, 22 Jun 2018 14:33:59 +1000 (AEST) Received: from localhost ([::1]:59170 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDlk-0005cn-QD for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 00:33:56 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39717) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDcz-0007iu-SK for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWDcx-0003Zt-Ol for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:53 -0400 Received: from ozlabs.org ([203.11.71.1]:54191) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fWDcx-0003YP-2E; Fri, 22 Jun 2018 00:24:51 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41BlpN58phz9s8f; Fri, 22 Jun 2018 14:24:44 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1529641484; bh=/02E3Ot4nEC5soMzKEWeplEFm65cLOiCPzc+FZJDpZg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mHYd21exyO3ZznrXfCO2PRNI8+vYEbzCkOK72cBbL1dJFrj6OUNCgiRsfnGsODT0s nGL7U+l45X4rSWbJR4Ls5AITJLiPnbnmjN4gmKvzQO7PTrqmYwB+27EitdjlTnEp2x iP/fP9U8LeDpbclEqZl6NF7GBXmlKXSxzI5u9BTk= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 22 Jun 2018 14:24:23 +1000 Message-Id: <20180622042437.14259-9-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180622042437.14259-1-david@gibson.dropbear.id.au> References: <20180622042437.14259-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PATCH 09/23] spapr: Add cpu_apply hook to capabilities X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" spapr capabilities have an apply hook to actually activate (or deactivate) the feature in the system at reset time. However, a number of capabilities affect the setup of cpus, and need to be applied to each of them - including hotplugged cpus for extra complication. To make this simpler, add an optional cpu_apply hook that is called from spapr_cpu_reset(). Signed-off-by: David Gibson Reviewed-by: Greg Kurz Reviewed-by: Cédric Le Goater --- hw/ppc/spapr_caps.c | 19 +++++++++++++++++++ hw/ppc/spapr_cpu_core.c | 2 ++ include/hw/ppc/spapr.h | 1 + 3 files changed, 22 insertions(+) diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c index dabed817d1..68a4243efc 100644 --- a/hw/ppc/spapr_caps.c +++ b/hw/ppc/spapr_caps.c @@ -59,6 +59,8 @@ typedef struct sPAPRCapabilityInfo { sPAPRCapPossible *possible; /* Make sure the virtual hardware can support this capability */ void (*apply)(sPAPRMachineState *spapr, uint8_t val, Error **errp); + void (*cpu_apply)(sPAPRMachineState *spapr, PowerPCCPU *cpu, + uint8_t val, Error **errp); } sPAPRCapabilityInfo; static void spapr_cap_get_bool(Object *obj, Visitor *v, const char *name, @@ -472,6 +474,23 @@ void spapr_caps_apply(sPAPRMachineState *spapr) } } +void spapr_caps_cpu_apply(sPAPRMachineState *spapr, PowerPCCPU *cpu) +{ + int i; + + for (i = 0; i < SPAPR_CAP_NUM; i++) { + sPAPRCapabilityInfo *info = &capability_table[i]; + + /* + * If the apply function can't set the desired level and thinks it's + * fatal, it should cause that. + */ + if (info->cpu_apply) { + info->cpu_apply(spapr, cpu, spapr->eff.caps[i], &error_fatal); + } + } +} + void spapr_caps_add_properties(sPAPRMachineClass *smc, Error **errp) { Error *local_err = NULL; diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index 67f1596c57..bfb94f650c 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -76,6 +76,8 @@ static void spapr_cpu_reset(void *opaque) spapr_cpu->slb_shadow_size = 0; spapr_cpu->dtl_addr = 0; spapr_cpu->dtl_size = 0; + + spapr_caps_cpu_apply(SPAPR_MACHINE(qdev_get_machine()), cpu); } void spapr_cpu_set_entry_state(PowerPCCPU *cpu, target_ulong nip, target_ulong r3) diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 9dbd6010f5..9dd46a72f6 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -800,6 +800,7 @@ static inline uint8_t spapr_get_cap(sPAPRMachineState *spapr, int cap) void spapr_caps_init(sPAPRMachineState *spapr); void spapr_caps_apply(sPAPRMachineState *spapr); +void spapr_caps_cpu_apply(sPAPRMachineState *spapr, PowerPCCPU *cpu); void spapr_caps_add_properties(sPAPRMachineClass *smc, Error **errp); int spapr_caps_post_migration(sPAPRMachineState *spapr); From patchwork Fri Jun 22 04:24:24 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 933072 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="aM4dpu9U"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Blxb4ZVHz9s2R for ; Fri, 22 Jun 2018 14:30:59 +1000 (AEST) Received: from localhost ([::1]:59157 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDir-0003eS-AL for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 00:30:57 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39724) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDd0-0007jE-4F for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWDcy-0003aR-1F for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:54 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:47459) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fWDcx-0003YL-7P; Fri, 22 Jun 2018 00:24:51 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41BlpN2yK7z9s8r; Fri, 22 Jun 2018 14:24:44 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1529641484; bh=4JLNuZOc3oROrWXV082ERH9/K7BvZEP4qZtFC1h7RlU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aM4dpu9UcGdHNHrerStkGtzRoD81FeGqx8sxpbhVMpG+BtuPzDnEJQvHf82NvzAzm rvbCBCyYPhOBSVwGDIlYlkS6h5IYjuRBeUFqOQq6/HGE/dddQE00D3v84z8Wl/zTBQ DZ8BPxCE7Q66pY8o89zIFkZ+Qt3O6wbBZR+YK7U4= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 22 Jun 2018 14:24:24 +1000 Message-Id: <20180622042437.14259-10-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180622042437.14259-1-david@gibson.dropbear.id.au> References: <20180622042437.14259-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 Subject: [Qemu-devel] [PATCH 10/23] target/ppc: Add kvmppc_hpt_needs_host_contiguous_pages() helper X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" KVM HV has a restriction that for HPT mode guests, guest pages must be hpa contiguous as well as gpa contiguous. We have to account for that in various places. We determine whether we're subject to this restriction from the SMMU information exposed by KVM. Planned cleanups to the way we handle this will require knowing whether this restriction is in play in wider parts of the code. So, expose a helper function which returns it. This does mean some redundant calls to kvm_get_smmu_info(), but they'll go away again with future cleanups. Signed-off-by: David Gibson Reviewed-by: Greg Kurz Reviewed-by: Cédric Le Goater --- target/ppc/kvm.c | 17 +++++++++++++++-- target/ppc/kvm_ppc.h | 6 ++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 5c0e313ca6..50b5d01432 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -406,9 +406,22 @@ target_ulong kvmppc_configure_v3_mmu(PowerPCCPU *cpu, } } +bool kvmppc_hpt_needs_host_contiguous_pages(void) +{ + PowerPCCPU *cpu = POWERPC_CPU(first_cpu); + static struct kvm_ppc_smmu_info smmu_info; + + if (!kvm_enabled()) { + return false; + } + + kvm_get_smmu_info(cpu, &smmu_info); + return !!(smmu_info.flags & KVM_PPC_PAGE_SIZES_REAL); +} + static bool kvm_valid_page_size(uint32_t flags, long rampgsize, uint32_t shift) { - if (!(flags & KVM_PPC_PAGE_SIZES_REAL)) { + if (!kvmppc_hpt_needs_host_contiguous_pages()) { return true; } @@ -445,7 +458,7 @@ static void kvm_fixup_page_sizes(PowerPCCPU *cpu) /* If we have HV KVM, we need to forbid CI large pages if our * host page size is smaller than 64K. */ - if (smmu_info.flags & KVM_PPC_PAGE_SIZES_REAL) { + if (kvmppc_hpt_needs_host_contiguous_pages()) { if (getpagesize() >= 0x10000) { cpu->hash64_opts->flags |= PPC_HASH64_CI_LARGEPAGE; } else { diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h index e2840e1d33..a7ddb8a5d6 100644 --- a/target/ppc/kvm_ppc.h +++ b/target/ppc/kvm_ppc.h @@ -70,6 +70,7 @@ int kvmppc_resize_hpt_prepare(PowerPCCPU *cpu, target_ulong flags, int shift); int kvmppc_resize_hpt_commit(PowerPCCPU *cpu, target_ulong flags, int shift); bool kvmppc_pvr_workaround_required(PowerPCCPU *cpu); +bool kvmppc_hpt_needs_host_contiguous_pages(void); bool kvmppc_is_mem_backend_page_size_ok(const char *obj_path); #else @@ -222,6 +223,11 @@ static inline uint64_t kvmppc_rma_size(uint64_t current_size, return ram_size; } +static inline bool kvmppc_hpt_needs_host_contiguous_pages(void) +{ + return false; +} + static inline bool kvmppc_is_mem_backend_page_size_ok(const char *obj_path) { return true; From patchwork Fri Jun 22 04:24:25 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 933084 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="hOItNJVe"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Bm665TJlz9s0W for ; Fri, 22 Jun 2018 14:38:22 +1000 (AEST) Received: from localhost ([::1]:59196 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDq0-0000QV-Dj for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 00:38:20 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39721) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDd0-0007j9-1J for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWDcx-0003Zh-Jx for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:53 -0400 Received: from ozlabs.org ([203.11.71.1]:43925) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fWDcw-0003YN-Vx; Fri, 22 Jun 2018 00:24:51 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41BlpN4KYrz9s8J; Fri, 22 Jun 2018 14:24:44 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1529641484; bh=nndXPzGNeXLekZzQg5M0EYOgYJSrozEaSHXM2IGeV/Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hOItNJVeRIHQ23pL7jChYsluqvcjmT/MC1nQv9eWbmHWjRInJjeME3HYYesfDPrPT 954DGuRVqApQy2wu9x46Zx3J8Z8xReeeZmFngXGvTiviAI6L5CBNEBVD0UDz1t3hyG 0VFDHF9RJoKojWvSuTnLP56MPvKfFWZZurxu3mU8= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 22 Jun 2018 14:24:25 +1000 Message-Id: <20180622042437.14259-11-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180622042437.14259-1-david@gibson.dropbear.id.au> References: <20180622042437.14259-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PATCH 11/23] spapr: split the IRQ allocation sequence X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Cédric Le Goater Today, when a device requests for IRQ number in a sPAPR machine, the spapr_irq_alloc() routine first scans the ICSState status array to find an empty slot and then performs the assignement of the selected numbers. Split this sequence in two distinct routines : spapr_irq_find() for lookups and spapr_irq_claim() for claiming the IRQ numbers. This will ease the introduction of a static layout of IRQ numbers. Signed-off-by: Cédric Le Goater Signed-off-by: David Gibson --- hw/ppc/spapr.c | 50 ++++++++++++++++++++++++++++++++++++++++++ hw/ppc/spapr_events.c | 18 +++++++++++---- hw/ppc/spapr_pci.c | 23 ++++++++++++++++--- hw/ppc/spapr_vio.c | 10 ++++++++- include/hw/ppc/spapr.h | 4 ++++ 5 files changed, 97 insertions(+), 8 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 4a0b679166..b7705c3944 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3816,6 +3816,36 @@ static int ics_find_free_block(ICSState *ics, int num, int alignnum) return -1; } +int spapr_irq_find(sPAPRMachineState *spapr, int num, bool align, Error **errp) +{ + ICSState *ics = spapr->ics; + int first = -1; + + assert(ics); + + /* + * MSIMesage::data is used for storing VIRQ so + * it has to be aligned to num to support multiple + * MSI vectors. MSI-X is not affected by this. + * The hint is used for the first IRQ, the rest should + * be allocated continuously. + */ + if (align) { + assert((num == 1) || (num == 2) || (num == 4) || + (num == 8) || (num == 16) || (num == 32)); + first = ics_find_free_block(ics, num, num); + } else { + first = ics_find_free_block(ics, num, 1); + } + + if (first < 0) { + error_setg(errp, "can't find a free %d-IRQ block", num); + return -1; + } + + return first + ics->offset; +} + /* * Allocate the IRQ number and set the IRQ type, LSI or MSI */ @@ -3894,6 +3924,26 @@ int spapr_irq_alloc_block(sPAPRMachineState *spapr, int num, bool lsi, return first; } +int spapr_irq_claim(sPAPRMachineState *spapr, int irq, bool lsi, Error **errp) +{ + ICSState *ics = spapr->ics; + + assert(ics); + + if (!ics_valid_irq(ics, irq)) { + error_setg(errp, "IRQ %d is invalid", irq); + return -1; + } + + if (!ICS_IRQ_FREE(ics, irq - ics->offset)) { + error_setg(errp, "IRQ %d is not free", irq); + return -1; + } + + spapr_irq_set_lsi(spapr, irq, lsi); + return 0; +} + void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num) { ICSState *ics = spapr->ics; diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c index 86836f0626..e4f5946a21 100644 --- a/hw/ppc/spapr_events.c +++ b/hw/ppc/spapr_events.c @@ -707,13 +707,18 @@ void spapr_clear_pending_events(sPAPRMachineState *spapr) void spapr_events_init(sPAPRMachineState *spapr) { + int epow_irq; + + epow_irq = spapr_irq_findone(spapr, &error_fatal); + + spapr_irq_claim(spapr, epow_irq, false, &error_fatal); + QTAILQ_INIT(&spapr->pending_events); spapr->event_sources = spapr_event_sources_new(); spapr_event_sources_register(spapr->event_sources, EVENT_CLASS_EPOW, - spapr_irq_alloc(spapr, 0, false, - &error_fatal)); + epow_irq); /* NOTE: if machine supports modern/dedicated hotplug event source, * we add it to the device-tree unconditionally. This means we may @@ -724,9 +729,14 @@ void spapr_events_init(sPAPRMachineState *spapr) * checking that it's enabled. */ if (spapr->use_hotplug_event_source) { + int hp_irq; + + hp_irq = spapr_irq_findone(spapr, &error_fatal); + + spapr_irq_claim(spapr, hp_irq, false, &error_fatal); + spapr_event_sources_register(spapr->event_sources, EVENT_CLASS_HOT_PLUG, - spapr_irq_alloc(spapr, 0, false, - &error_fatal)); + hp_irq); } spapr->epow_notifier.notify = spapr_powerdown_req; diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index f936ce63ef..497b896c7d 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -279,6 +279,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr, spapr_pci_msi *msi; int *config_addr_key; Error *err = NULL; + int i; /* Fins sPAPRPHBState */ phb = spapr_pci_find_phb(spapr, buid); @@ -371,8 +372,7 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr, } /* Allocate MSIs */ - irq = spapr_irq_alloc_block(spapr, req_num, false, - ret_intr_type == RTAS_TYPE_MSI, &err); + irq = spapr_irq_find(spapr, req_num, ret_intr_type == RTAS_TYPE_MSI, &err); if (err) { error_reportf_err(err, "Can't allocate MSIs for device %x: ", config_addr); @@ -380,6 +380,16 @@ static void rtas_ibm_change_msi(PowerPCCPU *cpu, sPAPRMachineState *spapr, return; } + for (i = 0; i < req_num; i++) { + spapr_irq_claim(spapr, irq + i, false, &err); + if (err) { + error_reportf_err(err, "Can't allocate MSIs for device %x: ", + config_addr); + rtas_st(rets, 0, RTAS_OUT_HW_ERROR); + return; + } + } + /* Release previous MSIs */ if (msi) { spapr_irq_free(spapr, msi->first_irq, msi->num); @@ -1698,7 +1708,14 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) uint32_t irq; Error *local_err = NULL; - irq = spapr_irq_alloc_block(spapr, 1, true, false, &local_err); + irq = spapr_irq_findone(spapr, &local_err); + if (local_err) { + error_propagate(errp, local_err); + error_prepend(errp, "can't allocate LSIs: "); + return; + } + + spapr_irq_claim(spapr, irq, true, &local_err); if (local_err) { error_propagate(errp, local_err); error_prepend(errp, "can't allocate LSIs: "); diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c index 4555c648a8..daf85130b5 100644 --- a/hw/ppc/spapr_vio.c +++ b/hw/ppc/spapr_vio.c @@ -475,7 +475,15 @@ static void spapr_vio_busdev_realize(DeviceState *qdev, Error **errp) dev->qdev.id = id; } - dev->irq = spapr_irq_alloc(spapr, dev->irq, false, &local_err); + if (!dev->irq) { + dev->irq = spapr_irq_findone(spapr, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + } + + spapr_irq_claim(spapr, dev->irq, false, &local_err); if (local_err) { error_propagate(errp, local_err); return; diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 9dd46a72f6..6bfdf5a2fb 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -776,6 +776,10 @@ int spapr_irq_alloc(sPAPRMachineState *spapr, int irq_hint, bool lsi, Error **errp); int spapr_irq_alloc_block(sPAPRMachineState *spapr, int num, bool lsi, bool align, Error **errp); +int spapr_irq_find(sPAPRMachineState *spapr, int num, bool align, + Error **errp); +#define spapr_irq_findone(spapr, errp) spapr_irq_find(spapr, 1, false, errp) +int spapr_irq_claim(sPAPRMachineState *spapr, int irq, bool lsi, Error **errp); void spapr_irq_free(sPAPRMachineState *spapr, int irq, int num); qemu_irq spapr_qirq(sPAPRMachineState *spapr, int irq); From patchwork Fri Jun 22 04:24:26 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 933067 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="mPU74wmQ"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Blqv72sSz9s4v for ; Fri, 22 Jun 2018 14:26:03 +1000 (AEST) Received: from localhost ([::1]:59128 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDe5-0008ED-Js for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 00:26:01 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39706) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDcz-0007i3-GJ for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:55 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWDcx-0003ZZ-II for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:53 -0400 Received: from ozlabs.org ([203.11.71.1]:35023) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fWDcw-0003YJ-TU; Fri, 22 Jun 2018 00:24:51 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41BlpN1fS4z9s76; Fri, 22 Jun 2018 14:24:44 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1529641484; bh=m05T2XFj3FxA5bAxC47MB8ys1YHP43N470/0NmsivWY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mPU74wmQ7vH2SxeAu6j36G8BQAdllBJrKYMMgUjnw2EMYirToZZNsfjKCde1lM0tk U0CiWTgzOl+oQ91LcLpc9bFWWa/TUWOucDyosEC69bG3ymWZSFMwYRSBBsVbYVW1Ki 58txGjGjz9QDcRum1W1pFUvS4+Ex1hZZCGV5YnDk= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 22 Jun 2018 14:24:26 +1000 Message-Id: <20180622042437.14259-12-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180622042437.14259-1-david@gibson.dropbear.id.au> References: <20180622042437.14259-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PATCH 12/23] spapr: remove unused spapr_irq routines X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Cédric Le Goater spapr_irq_alloc_block and spapr_irq_alloc() are now deprecated. Signed-off-by: Cédric Le Goater Reviewed-by: David Gibson Signed-off-by: David Gibson --- hw/ppc/spapr.c | 80 +----------------------------------------- include/hw/ppc/spapr.h | 4 --- 2 files changed, 1 insertion(+), 83 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index b7705c3944..78186500e9 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3846,84 +3846,6 @@ int spapr_irq_find(sPAPRMachineState *spapr, int num, bool align, Error **errp) return first + ics->offset; } -/* - * Allocate the IRQ number and set the IRQ type, LSI or MSI - */ -static void spapr_irq_set_lsi(sPAPRMachineState *spapr, int irq, bool lsi) -{ - ics_set_irq_type(spapr->ics, irq - spapr->ics->offset, lsi); -} - -int spapr_irq_alloc(sPAPRMachineState *spapr, int irq_hint, bool lsi, - Error **errp) -{ - ICSState *ics = spapr->ics; - int irq; - - assert(ics); - - if (irq_hint) { - if (!ICS_IRQ_FREE(ics, irq_hint - ics->offset)) { - error_setg(errp, "can't allocate IRQ %d: already in use", irq_hint); - return -1; - } - irq = irq_hint; - } else { - irq = ics_find_free_block(ics, 1, 1); - if (irq < 0) { - error_setg(errp, "can't allocate IRQ: no IRQ left"); - return -1; - } - irq += ics->offset; - } - - spapr_irq_set_lsi(spapr, irq, lsi); - trace_spapr_irq_alloc(irq); - - return irq; -} - -/* - * Allocate block of consecutive IRQs, and return the number of the first IRQ in - * the block. If align==true, aligns the first IRQ number to num. - */ -int spapr_irq_alloc_block(sPAPRMachineState *spapr, int num, bool lsi, - bool align, Error **errp) -{ - ICSState *ics = spapr->ics; - int i, first = -1; - - assert(ics); - - /* - * MSIMesage::data is used for storing VIRQ so - * it has to be aligned to num to support multiple - * MSI vectors. MSI-X is not affected by this. - * The hint is used for the first IRQ, the rest should - * be allocated continuously. - */ - if (align) { - assert((num == 1) || (num == 2) || (num == 4) || - (num == 8) || (num == 16) || (num == 32)); - first = ics_find_free_block(ics, num, num); - } else { - first = ics_find_free_block(ics, num, 1); - } - if (first < 0) { - error_setg(errp, "can't find a free %d-IRQ block", num); - return -1; - } - - first += ics->offset; - for (i = first; i < first + num; ++i) { - spapr_irq_set_lsi(spapr, i, lsi); - } - - trace_spapr_irq_alloc_block(first, num, lsi, align); - - return first; -} - int spapr_irq_claim(sPAPRMachineState *spapr, int irq, bool lsi, Error **errp) { ICSState *ics = spapr->ics; @@ -3940,7 +3862,7 @@ int spapr_irq_claim(sPAPRMachineState *spapr, int irq, bool lsi, Error **errp) return -1; } - spapr_irq_set_lsi(spapr, irq, lsi); + ics_set_irq_type(ics, irq - ics->offset, lsi); return 0; } diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 6bfdf5a2fb..8a9142244f 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -772,10 +772,6 @@ int spapr_get_vcpu_id(PowerPCCPU *cpu); void spapr_set_vcpu_id(PowerPCCPU *cpu, int cpu_index, Error **errp); PowerPCCPU *spapr_find_cpu(int vcpu_id); -int spapr_irq_alloc(sPAPRMachineState *spapr, int irq_hint, bool lsi, - Error **errp); -int spapr_irq_alloc_block(sPAPRMachineState *spapr, int num, bool lsi, - bool align, Error **errp); int spapr_irq_find(sPAPRMachineState *spapr, int num, bool align, Error **errp); #define spapr_irq_findone(spapr, errp) spapr_irq_find(spapr, 1, false, errp) From patchwork Fri Jun 22 04:24:27 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 933093 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="KuUNCb0B"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41BmBl1Fssz9s0W for ; Fri, 22 Jun 2018 14:42:23 +1000 (AEST) Received: from localhost ([::1]:59218 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDts-0003KN-TX for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 00:42:20 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39823) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDd2-0007lh-Rk for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWDd0-0003cV-Vs for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:56 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:56931) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fWDd0-0003ag-Dw; Fri, 22 Jun 2018 00:24:54 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41BlpQ0NkDz9sBR; Fri, 22 Jun 2018 14:24:44 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1529641486; bh=M8aQkUpC2cOVnLCKzRST3f7Xq+oPzCoVI7MvJSUZr0o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KuUNCb0BqrhrMad9SVg2KvBGhwBvv2rIsohzIZz9TAyvxiI8QycK+hRkmKSxTQgeW E1+Dhtg/yUDbjGHLk8UMhIbuAM+NtdyWvy/Uvv5dYCC8G8T+sXzwr42nV9/gUYvX9u 5IkQN9+/Fri9H8K1o+72G4HQui/Gp3Xv5zi4BYak= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 22 Jun 2018 14:24:27 +1000 Message-Id: <20180622042437.14259-13-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180622042437.14259-1-david@gibson.dropbear.id.au> References: <20180622042437.14259-1-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 Subject: [Qemu-devel] [PATCH 13/23] fpu_helper.c: fix helper_fpscr_clrbit() function X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, John Arbuckle , groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: John Arbuckle Fix the helper_fpscr_clrbit() function so it correctly sets the FEX and VX bits. Determining the value for the Floating Point Status and Control Register's (FPSCR) FEX bit is suppose to be done like this: FEX = (VX & VE) | (OX & OE) | (UX & UE) | (ZX & ZE) | (XX & XE)) It is described as "the logical OR of all the floating-point exception bits masked by their respective enable bits". It was not implemented correctly. The value of FEX would stay on even when all other bits were set to off. The VX bit is described as "the logical OR of all of the invalid operation exceptions". This bit was also not implemented correctly. It too would stay on when all the other bits were set to off. My main source of information is an IBM document called: PowerPC Microprocessor Family: The Programming Environments for 32-Bit Microprocessors Page 62 is where the FPSCR information is located. This is an older copy than the one I use but it is still very useful: https://www.pdfdrive.net/powerpc-microprocessor-family-the-programming-environments-for-32-e3087633.html I use a G3 and G5 iMac to compare bit values with QEMU. This patch fixed all the problems I was having with these bits. Signed-off-by: John Arbuckle [dwg: Re-wrapped commit message] Signed-off-by: David Gibson --- target/ppc/fpu_helper.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/target/ppc/fpu_helper.c b/target/ppc/fpu_helper.c index d31a933cbb..7714bfe0f9 100644 --- a/target/ppc/fpu_helper.c +++ b/target/ppc/fpu_helper.c @@ -325,6 +325,34 @@ void helper_fpscr_clrbit(CPUPPCState *env, uint32_t bit) case FPSCR_RN: fpscr_set_rounding_mode(env); break; + case FPSCR_VXSNAN: + case FPSCR_VXISI: + case FPSCR_VXIDI: + case FPSCR_VXZDZ: + case FPSCR_VXIMZ: + case FPSCR_VXVC: + case FPSCR_VXSOFT: + case FPSCR_VXSQRT: + case FPSCR_VXCVI: + if (!fpscr_ix) { + /* Set VX bit to zero */ + env->fpscr &= ~(1 << FPSCR_VX); + } + break; + case FPSCR_OX: + case FPSCR_UX: + case FPSCR_ZX: + case FPSCR_XX: + case FPSCR_VE: + case FPSCR_OE: + case FPSCR_UE: + case FPSCR_ZE: + case FPSCR_XE: + if (!fpscr_eex) { + /* Set the FEX bit */ + env->fpscr &= ~(1 << FPSCR_FEX); + } + break; default: break; } From patchwork Fri Jun 22 04:24:28 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 933070 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="hWb/8ndX"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Bltz36Ppz9s2R for ; Fri, 22 Jun 2018 14:28:43 +1000 (AEST) Received: from localhost ([::1]:59145 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDgf-0001rU-4H for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 00:28:41 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39790) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDd2-0007ld-0p for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWDd0-0003c5-K3 for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:55 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:41251) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fWDd0-0003aE-2L; Fri, 22 Jun 2018 00:24:54 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41BlpP4ZxCz9sBK; Fri, 22 Jun 2018 14:24:44 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1529641485; bh=SmVfq5yUdFq/bu5sn9/D0HT0S5QmwzDMGsMchaU99C8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hWb/8ndXoWWhzf4byAa+H0/ErkMhP20l3KxKnHpVizrP7wuHVoIfRNwWDehh+qqyE An4LaWV5noYcPXUKqerQluoYFEX/Gp42IYDx90qYg8buxtRfATy+f9ZDxxtlOGXoFq 7raIJRloYxbic0GVfKpxv318AtUODn8lT5bBh8D0= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 22 Jun 2018 14:24:28 +1000 Message-Id: <20180622042437.14259-14-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180622042437.14259-1-david@gibson.dropbear.id.au> References: <20180622042437.14259-1-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 Subject: [Qemu-devel] [PATCH 14/23] sm501: Fix hardware cursor color conversion X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, Sebastian Bauer , qemu-devel@nongnu.org, agraf@suse.de, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Sebastian Bauer According to the sm501 specs the hardware cursor colors are to be given in the rgb565 format, but the code currently interprets them as bgr565. Therefore, the colors of the hardware cursors are wrong in the QEMU display, e.g., the standard mouse pointer of AmigaOS appears blue instead of red. This change fixes this issue by replacing the existing naive bgr565 => rgb888 conversion with a standard rgb565 => rgb888 one that also scales the color component values properly. Signed-off-by: Sebastian Bauer Signed-off-by: David Gibson --- hw/display/sm501.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hw/display/sm501.c b/hw/display/sm501.c index ca0840f6fa..8206ae81a1 100644 --- a/hw/display/sm501.c +++ b/hw/display/sm501.c @@ -652,9 +652,9 @@ static inline void get_hwc_palette(SM501State *state, int crt, uint8_t *palette) } else { rgb565 = color_reg & 0xFFFF; } - palette[i * 3 + 0] = (rgb565 << 3) & 0xf8; /* red */ - palette[i * 3 + 1] = (rgb565 >> 3) & 0xfc; /* green */ - palette[i * 3 + 2] = (rgb565 >> 8) & 0xf8; /* blue */ + palette[i * 3 + 0] = ((rgb565 >> 11) * 527 + 23) >> 6; /* r */ + palette[i * 3 + 1] = (((rgb565 >> 5) & 0x3f) * 259 + 33) >> 6; /* g */ + palette[i * 3 + 2] = ((rgb565 & 0x1f) * 527 + 23) >> 6; /* b */ } } From patchwork Fri Jun 22 04:24:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 933092 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="ODPuk+fA"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Bm9Q5ftVz9s01 for ; Fri, 22 Jun 2018 14:41:13 +1000 (AEST) Received: from localhost ([::1]:59213 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDsk-0002YW-IJ for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 00:41:10 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39922) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDd5-0007na-Ja for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:25:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWDd3-0003eJ-GR for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:59 -0400 Received: from ozlabs.org ([203.11.71.1]:48411) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fWDd2-0003cJ-P1; Fri, 22 Jun 2018 00:24:57 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41BlpQ3k5rz9sBJ; Fri, 22 Jun 2018 14:24:44 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1529641486; bh=mibbBfDv2VFUbRVnNO+PsjzgrZmShFebtR4HjSYnUcs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ODPuk+fAr6Hz+c7JGl0hrNYzPnH73/3hepXJJrDkAlQwngQdUbAmqLgagC5hN1rUV 2ajPq12KzAmGeEkHQDJBzj9+h5KrL6qEwdwniJps5vhUGiG/IsoQc6WyNrSYMOk5fZ IC8RHBtYOiXyWYlQt1ShPe0bi4LuT5uDCknh9clg= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 22 Jun 2018 14:24:29 +1000 Message-Id: <20180622042437.14259-15-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180622042437.14259-1-david@gibson.dropbear.id.au> References: <20180622042437.14259-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PATCH 15/23] ppc4xx_i2c: Remove unimplemented sdata and intr registers X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: BALATON Zoltan We don't emulate slave mode so related registers are not needed. [lh]sadr are only retained to avoid too many warnings and simplify debugging but sdata is not even correct because device has a 4 byte FIFO instead so just remove this unimplemented register for now. The intr register is also not implemented correctly, it is for diagnostics and normally not even visible on device without explicitly enabling it. As no guests are known to need this remove it as well. Signed-off-by: BALATON Zoltan Signed-off-by: David Gibson --- hw/i2c/ppc4xx_i2c.c | 16 +--------------- include/hw/i2c/ppc4xx_i2c.h | 4 +--- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/hw/i2c/ppc4xx_i2c.c b/hw/i2c/ppc4xx_i2c.c index d1936dbdca..4e0aaae1fc 100644 --- a/hw/i2c/ppc4xx_i2c.c +++ b/hw/i2c/ppc4xx_i2c.c @@ -3,7 +3,7 @@ * * Copyright (c) 2007 Jocelyn Mayer * Copyright (c) 2012 François Revol - * Copyright (c) 2016 BALATON Zoltan + * Copyright (c) 2016-2018 BALATON Zoltan * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -63,7 +63,6 @@ static void ppc4xx_i2c_reset(DeviceState *s) i2c->mdcntl = 0; i2c->sts = 0; i2c->extsts = 0x8f; - i2c->sdata = 0; i2c->lsadr = 0; i2c->hsadr = 0; i2c->clkdiv = 0; @@ -71,7 +70,6 @@ static void ppc4xx_i2c_reset(DeviceState *s) i2c->xfrcnt = 0; i2c->xtcntlss = 0; i2c->directcntl = 0xf; - i2c->intr = 0; } static inline bool ppc4xx_i2c_is_master(PPC4xxI2CState *i2c) @@ -139,9 +137,6 @@ static uint64_t ppc4xx_i2c_readb(void *opaque, hwaddr addr, unsigned int size) TYPE_PPC4xx_I2C, __func__); } break; - case 2: - ret = i2c->sdata; - break; case 4: ret = i2c->lmadr; break; @@ -181,9 +176,6 @@ static uint64_t ppc4xx_i2c_readb(void *opaque, hwaddr addr, unsigned int size) case 16: ret = i2c->directcntl; break; - case 17: - ret = i2c->intr; - break; default: if (addr < PPC4xx_I2C_MEM_SIZE) { qemu_log_mask(LOG_UNIMP, "%s: Unimplemented register 0x%" @@ -229,9 +221,6 @@ static void ppc4xx_i2c_writeb(void *opaque, hwaddr addr, uint64_t value, } } break; - case 2: - i2c->sdata = value; - break; case 4: i2c->lmadr = value; if (i2c_bus_busy(i2c->bus)) { @@ -302,9 +291,6 @@ static void ppc4xx_i2c_writeb(void *opaque, hwaddr addr, uint64_t value, case 16: i2c->directcntl = value & 0x7; break; - case 17: - i2c->intr = value; - break; default: if (addr < PPC4xx_I2C_MEM_SIZE) { qemu_log_mask(LOG_UNIMP, "%s: Unimplemented register 0x%" diff --git a/include/hw/i2c/ppc4xx_i2c.h b/include/hw/i2c/ppc4xx_i2c.h index 3c603071bd..e4b6ded855 100644 --- a/include/hw/i2c/ppc4xx_i2c.h +++ b/include/hw/i2c/ppc4xx_i2c.h @@ -3,7 +3,7 @@ * * Copyright (c) 2007 Jocelyn Mayer * Copyright (c) 2012 François Revol - * Copyright (c) 2016 BALATON Zoltan + * Copyright (c) 2016-2018 BALATON Zoltan * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -49,7 +49,6 @@ typedef struct PPC4xxI2CState { uint8_t mdcntl; uint8_t sts; uint8_t extsts; - uint8_t sdata; uint8_t lsadr; uint8_t hsadr; uint8_t clkdiv; @@ -57,7 +56,6 @@ typedef struct PPC4xxI2CState { uint8_t xfrcnt; uint8_t xtcntlss; uint8_t directcntl; - uint8_t intr; } PPC4xxI2CState; #endif /* PPC4XX_I2C_H */ From patchwork Fri Jun 22 04:24:30 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 933096 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="G8+uP2FO"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41BmGw15lGz9s0W for ; Fri, 22 Jun 2018 14:46:00 +1000 (AEST) Received: from localhost ([::1]:59242 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDxN-0005oD-S5 for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 00:45:57 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39828) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDd2-0007li-UV for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWDd0-0003cB-Kg for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:56 -0400 Received: from ozlabs.org ([203.11.71.1]:39215) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fWDcz-0003aV-Ur; Fri, 22 Jun 2018 00:24:54 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41BlpP5TMdz9s9T; Fri, 22 Jun 2018 14:24:44 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1529641485; bh=s4/B+4agv9pdc4PMSSfbW4vNF6W9ZQYZw0fQHucUwfk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=G8+uP2FOEiDDG8OsoiAVhi8dr6qMaly/9Sp5syELZeDP138UR5QETEGl18NNdje/O BO33MRXZ4hehZBTQO7ULbWAsKKJwOqKeIaaXbOtMVgvbB7O9xq7EWXkgk5uI5ReEz6 wuNrNkJcueXIXxLUgxJV1C+ixsqOfzg3p1MRuffM= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 22 Jun 2018 14:24:30 +1000 Message-Id: <20180622042437.14259-16-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180622042437.14259-1-david@gibson.dropbear.id.au> References: <20180622042437.14259-1-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PATCH 16/23] ppc4xx_i2c: Implement directcntl register X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: BALATON Zoltan As well as being able to generate its own i2c transactions, the ppc4xx i2c controller has a DIRECTCNTL register which allows explicit control of the i2c lines. Using this register an OS can directly bitbang i2c operations. In order to let emulated i2c devices respond to this, we need to wire up the DIRECTCNTL register to qemu's bitbanged i2c handling code. Signed-off-by: BALATON Zoltan Signed-off-by: David Gibson --- default-configs/ppc-softmmu.mak | 1 + default-configs/ppcemb-softmmu.mak | 1 + hw/i2c/ppc4xx_i2c.c | 14 +++++++++++++- include/hw/i2c/ppc4xx_i2c.h | 4 ++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/default-configs/ppc-softmmu.mak b/default-configs/ppc-softmmu.mak index abeeb0418a..851b4afc21 100644 --- a/default-configs/ppc-softmmu.mak +++ b/default-configs/ppc-softmmu.mak @@ -26,6 +26,7 @@ CONFIG_USB_EHCI_SYSBUS=y CONFIG_SM501=y CONFIG_IDE_SII3112=y CONFIG_I2C=y +CONFIG_BITBANG_I2C=y # For Macs CONFIG_MAC=y diff --git a/default-configs/ppcemb-softmmu.mak b/default-configs/ppcemb-softmmu.mak index 67d18b2e0e..37af1930b3 100644 --- a/default-configs/ppcemb-softmmu.mak +++ b/default-configs/ppcemb-softmmu.mak @@ -19,3 +19,4 @@ CONFIG_USB_EHCI_SYSBUS=y CONFIG_SM501=y CONFIG_IDE_SII3112=y CONFIG_I2C=y +CONFIG_BITBANG_I2C=y diff --git a/hw/i2c/ppc4xx_i2c.c b/hw/i2c/ppc4xx_i2c.c index 4e0aaae1fc..fca80d695a 100644 --- a/hw/i2c/ppc4xx_i2c.c +++ b/hw/i2c/ppc4xx_i2c.c @@ -30,6 +30,7 @@ #include "cpu.h" #include "hw/hw.h" #include "hw/i2c/ppc4xx_i2c.h" +#include "bitbang_i2c.h" #define PPC4xx_I2C_MEM_SIZE 18 @@ -46,6 +47,11 @@ #define IIC_XTCNTLSS_SRST (1 << 0) +#define IIC_DIRECTCNTL_SDAC (1 << 3) +#define IIC_DIRECTCNTL_SCLC (1 << 2) +#define IIC_DIRECTCNTL_MSDA (1 << 1) +#define IIC_DIRECTCNTL_MSCL (1 << 0) + static void ppc4xx_i2c_reset(DeviceState *s) { PPC4xxI2CState *i2c = PPC4xx_I2C(s); @@ -289,7 +295,12 @@ static void ppc4xx_i2c_writeb(void *opaque, hwaddr addr, uint64_t value, i2c->xtcntlss = value; break; case 16: - i2c->directcntl = value & 0x7; + i2c->directcntl = value & (IIC_DIRECTCNTL_SDAC & IIC_DIRECTCNTL_SCLC); + i2c->directcntl |= (value & IIC_DIRECTCNTL_SCLC ? 1 : 0); + bitbang_i2c_set(i2c->bitbang, BITBANG_I2C_SCL, + i2c->directcntl & IIC_DIRECTCNTL_MSCL); + i2c->directcntl |= bitbang_i2c_set(i2c->bitbang, BITBANG_I2C_SDA, + (value & IIC_DIRECTCNTL_SDAC) != 0) << 1; break; default: if (addr < PPC4xx_I2C_MEM_SIZE) { @@ -322,6 +333,7 @@ static void ppc4xx_i2c_init(Object *o) sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem); sysbus_init_irq(SYS_BUS_DEVICE(s), &s->irq); s->bus = i2c_init_bus(DEVICE(s), "i2c"); + s->bitbang = bitbang_i2c_init(s->bus); } static void ppc4xx_i2c_class_init(ObjectClass *klass, void *data) diff --git a/include/hw/i2c/ppc4xx_i2c.h b/include/hw/i2c/ppc4xx_i2c.h index e4b6ded855..ea6c8e1a58 100644 --- a/include/hw/i2c/ppc4xx_i2c.h +++ b/include/hw/i2c/ppc4xx_i2c.h @@ -31,6 +31,9 @@ #include "hw/sysbus.h" #include "hw/i2c/i2c.h" +/* from hw/i2c/bitbang_i2c.h */ +typedef struct bitbang_i2c_interface bitbang_i2c_interface; + #define TYPE_PPC4xx_I2C "ppc4xx-i2c" #define PPC4xx_I2C(obj) OBJECT_CHECK(PPC4xxI2CState, (obj), TYPE_PPC4xx_I2C) @@ -42,6 +45,7 @@ typedef struct PPC4xxI2CState { I2CBus *bus; qemu_irq irq; MemoryRegion iomem; + bitbang_i2c_interface *bitbang; uint8_t mdata; uint8_t lmadr; uint8_t hmadr; From patchwork Fri Jun 22 04:24:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 933091 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="Q3F2oqa/"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Bm8b1vksz9s01 for ; Fri, 22 Jun 2018 14:40:31 +1000 (AEST) Received: from localhost ([::1]:59206 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDs4-0001vP-UA for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 00:40:28 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39716) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDcz-0007is-S4 for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWDcx-0003a0-PS for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:53 -0400 Received: from ozlabs.org ([203.11.71.1]:34481) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fWDcx-0003YU-Bj; Fri, 22 Jun 2018 00:24:51 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41BlpP1N8hz9s7M; Fri, 22 Jun 2018 14:24:44 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1529641485; bh=3/36QlZ2urOPp3rZnxef8W2T43FFTi5nHAA82CXSisI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Q3F2oqa/2SnQncXoarK66el87YxBEPS8kKcfk1SUkAjs5HRa0JN/BwVPQhURlvt+D rkqvIF6eFng23nBG40Xg0hxY2ZbVMsaNf2V27lu9JkgkYoE/MLAzLH615mUJwPili9 30wwOT/ixB5t4u/Unj4iNuTlGAyLK96u2x12yjmw= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 22 Jun 2018 14:24:31 +1000 Message-Id: <20180622042437.14259-17-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180622042437.14259-1-david@gibson.dropbear.id.au> References: <20180622042437.14259-1-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PATCH 17/23] target/ppc: Add missing opcode for icbt on PPC440 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: BALATON Zoltan According to PPC440 User Manual PPC440 has multiple opcodes for icbt instruction: one for compatibility with older cores and two 440 specific opcodes one of which is defined in BookE. QEMU only implements two of these, add the missing one. Signed-off-by: BALATON Zoltan Signed-off-by: David Gibson --- target/ppc/translate.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 5fe1ba6555..3a215a1dc6 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -6707,6 +6707,8 @@ GEN_HANDLER_E(mbar, 0x1F, 0x16, 0x1a, 0x001FF801, GEN_HANDLER(msync_4xx, 0x1F, 0x16, 0x12, 0x03FFF801, PPC_BOOKE), GEN_HANDLER2_E(icbt_440, "icbt", 0x1F, 0x16, 0x00, 0x03E00001, PPC_BOOKE, PPC2_BOOKE206), +GEN_HANDLER2(icbt_440, "icbt", 0x1F, 0x06, 0x08, 0x03E00001, + PPC_440_SPEC), GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC), GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC), GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC), From patchwork Fri Jun 22 04:24:32 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 933095 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="QFtCAv3D"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41BmDr67DKz9s0W for ; Fri, 22 Jun 2018 14:44:12 +1000 (AEST) Received: from localhost ([::1]:59231 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDve-0004SA-HU for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 00:44:10 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40260) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDdX-0008MT-S4 for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:25:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWDd2-0003dh-Sy for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:25:27 -0400 Received: from ozlabs.org ([203.11.71.1]:60257) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fWDd0-0003ao-Dl; Fri, 22 Jun 2018 00:24:56 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41BlpQ26gLz9sBQ; Fri, 22 Jun 2018 14:24:44 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1529641486; bh=sMMDedKgvRpEv3mRCPoB3o+VZh9jTMynq/ZpiX/6V4Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QFtCAv3D0lQcHyQ+kysnUZxSsLcVt4vPhJQQBp4K5loSk+jrScZlwFMbJavregNgJ Q8fVwwjBloyI1D1IqbWnPj01EckpX1rkuW71ofiRnVdjR0ndOHqm/RXjgNduitw/0Q 88JUXo9AsjBxusuM7S0pMesqfqlp88ty11NPHv5k= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 22 Jun 2018 14:24:32 +1000 Message-Id: <20180622042437.14259-18-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180622042437.14259-1-david@gibson.dropbear.id.au> References: <20180622042437.14259-1-david@gibson.dropbear.id.au> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PATCH 18/23] pseries: Update SLOF firmware image to qemu-slof-20180621 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Alexey Kardashevskiy The changes are: 1. fixed broken_sc1; 2. added switching between boot consoles; 3. added PXE boot. The full list is: > lib/libnet/pxelinux: Fix two off-by-one bugs in the pxelinux.cfg parser > lib/libnet/pxelinux: Make the size handling for pxelinux_load_cfg more logical > libc: Add a simple implementation of an assert() function > libnet: Support UUID-based pxelinux.cfg file names > slof: Add a helper function to get the contents of a property in C code > libnet: Add support for DHCPv4 options 209 and 210 > libnet: Wire up pxelinux.cfg network booting > libnet: Add functions for downloading and parsing pxelinux.cfg files > libnet: Put code for determing TFTP error strings into a separate function > libc: Add the snprintf() function > libnet: Pass ip_version via struct filename_ip > resolve ihandle and xt handle in the input command (like for the output) > Fix output word > obp-tftp: Make sure to not overwrite paflof in memory > libnet: Get rid of unused huge_load and block_size parameters > libc: Check for NULL pointers in free() > libc: Implement strrchr() > libnet: Get rid of unnecessary (char *) casts > broken_sc1: check for H_PRIVILEGE > OF: Use new property "stdout-path" for boot console Signed-off-by: Alexey Kardashevskiy Signed-off-by: David Gibson --- pc-bios/README | 2 +- pc-bios/slof.bin | Bin 913880 -> 924840 bytes roms/SLOF | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pc-bios/README b/pc-bios/README index a843e1e8b1..99e15a737b 100644 --- a/pc-bios/README +++ b/pc-bios/README @@ -17,7 +17,7 @@ - SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware implementation for certain IBM POWER hardware. The sources are at https://github.com/aik/SLOF, and the image currently in qemu is - built from git tag qemu-slof-20171214. + built from git tag qemu-slof-20180621. - sgabios (the Serial Graphics Adapter option ROM) provides a means for legacy x86 software to communicate with an attached serial console as diff --git a/pc-bios/slof.bin b/pc-bios/slof.bin index d46c83efb706e4664fec834234ba69d96ede3473..4e0e33f8297888ca8e143be784c30ce404f072cd 100644 GIT binary patch delta 231859 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 delta 221666 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 U&)nGEW5@N|C;#^jU!U~<0rFLY<^TWy diff --git a/roms/SLOF b/roms/SLOF index 2317427ce7..7d37babcfa 160000 --- a/roms/SLOF +++ b/roms/SLOF @@ -1 +1 @@ -Subproject commit 2317427ce76006723f7ae103a6998ab41dd79c68 +Subproject commit 7d37babcfa48a6eb08e726a8d13b745cb2eebe1c From patchwork Fri Jun 22 04:24:33 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 933083 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="i3Y1OHzB"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Bm4F6NDHz9s01 for ; Fri, 22 Jun 2018 14:36:45 +1000 (AEST) Received: from localhost ([::1]:59187 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDoR-0007kf-I6 for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 00:36:43 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39837) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDd3-0007lj-51 for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWDd0-0003bu-BL for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:57 -0400 Received: from ozlabs.org ([203.11.71.1]:44979) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fWDcz-0003Zy-Lr; Fri, 22 Jun 2018 00:24:54 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41BlpP2hHcz9sBD; Fri, 22 Jun 2018 14:24:44 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1529641485; bh=YDEyA+TrsW7RJ+g+8aqO9tyJZwYsVqFeyTUgP4pJYZA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=i3Y1OHzBKkoiNsQtIDzxtMp5q8XKg+X2jEXal02Oh/usWvtUwn1y3YqK6lwWJdlB7 OpTDuwXkssIJpdo14+O3ugfrmppWOepq1K3iegRrqfjaiMHBmvSG2Ekb+1mY6pOY+P hEbD2ZMH1YEqvY4r69BlUZ9VdSrOlUAWE/AI4Dgo= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 22 Jun 2018 14:24:33 +1000 Message-Id: <20180622042437.14259-19-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180622042437.14259-1-david@gibson.dropbear.id.au> References: <20180622042437.14259-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PATCH 19/23] spapr: Maximum (HPT) pagesize property X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The way the POWER Hash Page Table (HPT) MMU is virtualized by KVM HV means that every page that the guest puts in the pagetables must be truly physically contiguous, not just GPA-contiguous. In effect this means that an HPT guest can't use any pagesizes greater than the host page size used to back its memory. At present we handle this by changing what we advertise to the guest based on the backing pagesizes. This is pretty bad, because it means the guest sees a different environment depending on what should be host configuration details. As a start on fixing this, we add a new capability parameter to the pseries machine type which gives the maximum allowed pagesizes for an HPT guest. For now we just create and validate the parameter without making it do anything. For backwards compatibility, on older machine types we set it to the max available page size for the host. For the 3.0 machine type, we fix it to 16, the intention being to only allow HPT pagesizes up to 64kiB by default in future. Signed-off-by: David Gibson Reviewed-by: Cédric Le Goater Reviewed-by: Greg Kurz --- hw/ppc/spapr.c | 12 +++++++++ hw/ppc/spapr_caps.c | 56 ++++++++++++++++++++++++++++++++++++++++++ include/hw/ppc/spapr.h | 4 ++- 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 78186500e9..70b150b098 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -63,6 +63,7 @@ #include "hw/virtio/vhost-scsi-common.h" #include "exec/address-spaces.h" +#include "exec/ram_addr.h" #include "hw/usb.h" #include "qemu/config-file.h" #include "qemu/error-report.h" @@ -4015,6 +4016,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data) smc->default_caps.caps[SPAPR_CAP_CFPC] = SPAPR_CAP_BROKEN; smc->default_caps.caps[SPAPR_CAP_SBBC] = SPAPR_CAP_BROKEN; smc->default_caps.caps[SPAPR_CAP_IBS] = SPAPR_CAP_BROKEN; + smc->default_caps.caps[SPAPR_CAP_HPT_MAXPAGESIZE] = 16; /* 64kiB */ spapr_caps_add_properties(smc, &error_abort); } @@ -4103,8 +4105,18 @@ static void spapr_machine_2_12_instance_options(MachineState *machine) static void spapr_machine_2_12_class_options(MachineClass *mc) { + sPAPRMachineClass *smc = SPAPR_MACHINE_CLASS(mc); + uint8_t mps; + spapr_machine_3_0_class_options(mc); SET_MACHINE_COMPAT(mc, SPAPR_COMPAT_2_12); + + if (kvmppc_hpt_needs_host_contiguous_pages()) { + mps = ctz64(qemu_getrampagesize()); + } else { + mps = 34; /* allow everything up to 16GiB, i.e. everything */ + } + smc->default_caps.caps[SPAPR_CAP_HPT_MAXPAGESIZE] = mps; } DEFINE_SPAPR_MACHINE(2_12, "2.12", false); diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c index 68a4243efc..6cdc0c94e7 100644 --- a/hw/ppc/spapr_caps.c +++ b/hw/ppc/spapr_caps.c @@ -27,6 +27,7 @@ #include "qapi/visitor.h" #include "sysemu/hw_accel.h" #include "target/ppc/cpu.h" +#include "target/ppc/mmu-hash64.h" #include "cpu-models.h" #include "kvm_ppc.h" @@ -144,6 +145,42 @@ out: g_free(val); } +static void spapr_cap_get_pagesize(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + sPAPRCapabilityInfo *cap = opaque; + sPAPRMachineState *spapr = SPAPR_MACHINE(obj); + uint8_t val = spapr_get_cap(spapr, cap->index); + uint64_t pagesize = (1ULL << val); + + visit_type_size(v, name, &pagesize, errp); +} + +static void spapr_cap_set_pagesize(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + sPAPRCapabilityInfo *cap = opaque; + sPAPRMachineState *spapr = SPAPR_MACHINE(obj); + uint64_t pagesize; + uint8_t val; + Error *local_err = NULL; + + visit_type_size(v, name, &pagesize, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + if (!is_power_of_2(pagesize)) { + error_setg(errp, "cap-%s must be a power of 2", cap->name); + return; + } + + val = ctz64(pagesize); + spapr->cmd_line_caps[cap->index] = true; + spapr->eff.caps[cap->index] = val; +} + static void cap_htm_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp) { if (!val) { @@ -267,6 +304,16 @@ static void cap_safe_indirect_branch_apply(sPAPRMachineState *spapr, #define VALUE_DESC_TRISTATE " (broken, workaround, fixed)" +static void cap_hpt_maxpagesize_apply(sPAPRMachineState *spapr, + uint8_t val, Error **errp) +{ + if (val < 12) { + error_setg(errp, "Require at least 4kiB hpt-max-page-size"); + } else if (val < 16) { + warn_report("Many guests require at least 64kiB hpt-max-page-size"); + } +} + sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = { [SPAPR_CAP_HTM] = { .name = "htm", @@ -326,6 +373,15 @@ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = { .possible = &cap_ibs_possible, .apply = cap_safe_indirect_branch_apply, }, + [SPAPR_CAP_HPT_MAXPAGESIZE] = { + .name = "hpt-max-page-size", + .description = "Maximum page size for Hash Page Table guests", + .index = SPAPR_CAP_HPT_MAXPAGESIZE, + .get = spapr_cap_get_pagesize, + .set = spapr_cap_set_pagesize, + .type = "int", + .apply = cap_hpt_maxpagesize_apply, + }, }; static sPAPRCapabilities default_caps_with_cpu(sPAPRMachineState *spapr, diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 8a9142244f..4bc9dbff96 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -66,8 +66,10 @@ typedef enum { #define SPAPR_CAP_SBBC 0x04 /* Indirect Branch Serialisation */ #define SPAPR_CAP_IBS 0x05 +/* HPT Maximum Page Size (encoded as a shift) */ +#define SPAPR_CAP_HPT_MAXPAGESIZE 0x06 /* Num Caps */ -#define SPAPR_CAP_NUM (SPAPR_CAP_IBS + 1) +#define SPAPR_CAP_NUM (SPAPR_CAP_HPT_MAXPAGESIZE + 1) /* * Capability Values From patchwork Fri Jun 22 04:24:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 933087 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="j85l4qzL"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Bm6h2yLbz9s47 for ; Fri, 22 Jun 2018 14:38:52 +1000 (AEST) Received: from localhost ([::1]:59199 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDqU-0000ia-5y for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 00:38:50 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39862) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDd3-0007ln-SA for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:25:00 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWDd1-0003d4-Ix for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:57 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:57465) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fWDd0-0003ak-Nd; Fri, 22 Jun 2018 00:24:55 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41BlpQ0zw4z9s9J; Fri, 22 Jun 2018 14:24:44 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1529641486; bh=FPzZ0ckImaG7yRY9eh52ye71NtIZTeYEc5kdpoaK2hY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=j85l4qzLXiktd7ye9eKn7bNJfqgKQ2IqjnaqI//STGyo2ZL21WAUuihGL8V+t3Saf gFPy4csD9gtmegkUmIr1kF9DIU5WnNo2zvxzllhwyIPXjFlrfbmDpaa2FM22LUYsjB dB/MjZdROEzjhIAwvL0GVcElx2bYTQLwNHrEhP54= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 22 Jun 2018 14:24:34 +1000 Message-Id: <20180622042437.14259-20-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180622042437.14259-1-david@gibson.dropbear.id.au> References: <20180622042437.14259-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 Subject: [Qemu-devel] [PATCH 20/23] spapr: Use maximum page size capability to simplify memory backend checking X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The way we used to handle KVM allowable guest pagesizes for PAPR guests required some convoluted checking of memory attached to the guest. The allowable pagesizes advertised to the guest cpus depended on the memory which was attached at boot, but then we needed to ensure that any memory later hotplugged didn't change which pagesizes were allowed. Now that we have an explicit machine option to control the allowable maximum pagesize we can simplify this. We just check all memory backends against that declared pagesize. We check base and cold-plugged memory at reset time, and hotplugged memory at pre_plug() time. Signed-off-by: David Gibson Reviewed-by: Cédric Le Goater Reviewed-by: Greg Kurz --- hw/ppc/spapr.c | 17 +++++++---------- hw/ppc/spapr_caps.c | 21 +++++++++++++++++++++ include/hw/ppc/spapr.h | 3 +++ target/ppc/kvm.c | 14 -------------- target/ppc/kvm_ppc.h | 6 ------ 5 files changed, 31 insertions(+), 30 deletions(-) diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 70b150b098..0d032a1ad0 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3192,11 +3192,13 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { const sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(hotplug_dev); + sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_dev); PCDIMMDevice *dimm = PC_DIMM(dev); PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); MemoryRegion *mr; uint64_t size; - char *mem_dev; + Object *memdev; + hwaddr pagesize; if (!smc->dr_lmb_enabled) { error_setg(errp, "Memory hotplug not supported for this machine"); @@ -3215,15 +3217,10 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, return; } - mem_dev = object_property_get_str(OBJECT(dimm), PC_DIMM_MEMDEV_PROP, NULL); - if (mem_dev && !kvmppc_is_mem_backend_page_size_ok(mem_dev)) { - error_setg(errp, "Memory backend has bad page size. " - "Use 'memory-backend-file' with correct mem-path."); - goto out; - } - -out: - g_free(mem_dev); + memdev = object_property_get_link(OBJECT(dimm), PC_DIMM_MEMDEV_PROP, + &error_abort); + pagesize = host_memory_backend_pagesize(MEMORY_BACKEND(memdev)); + spapr_check_pagesize(spapr, pagesize, errp); } struct sPAPRDIMMState { diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c index 6cdc0c94e7..722b213d9a 100644 --- a/hw/ppc/spapr_caps.c +++ b/hw/ppc/spapr_caps.c @@ -26,6 +26,7 @@ #include "qapi/error.h" #include "qapi/visitor.h" #include "sysemu/hw_accel.h" +#include "exec/ram_addr.h" #include "target/ppc/cpu.h" #include "target/ppc/mmu-hash64.h" #include "cpu-models.h" @@ -304,14 +305,34 @@ static void cap_safe_indirect_branch_apply(sPAPRMachineState *spapr, #define VALUE_DESC_TRISTATE " (broken, workaround, fixed)" +void spapr_check_pagesize(sPAPRMachineState *spapr, hwaddr pagesize, + Error **errp) +{ + hwaddr maxpagesize = (1ULL << spapr->eff.caps[SPAPR_CAP_HPT_MAXPAGESIZE]); + + if (!kvmppc_hpt_needs_host_contiguous_pages()) { + return; + } + + if (maxpagesize > pagesize) { + error_setg(errp, + "Can't support %"HWADDR_PRIu" kiB guest pages with %" + HWADDR_PRIu" kiB host pages with this KVM implementation", + maxpagesize >> 10, pagesize >> 10); + } +} + static void cap_hpt_maxpagesize_apply(sPAPRMachineState *spapr, uint8_t val, Error **errp) { if (val < 12) { error_setg(errp, "Require at least 4kiB hpt-max-page-size"); + return; } else if (val < 16) { warn_report("Many guests require at least 64kiB hpt-max-page-size"); } + + spapr_check_pagesize(spapr, qemu_getrampagesize(), errp); } sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = { diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 4bc9dbff96..7e028164ba 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -806,4 +806,7 @@ void spapr_caps_cpu_apply(sPAPRMachineState *spapr, PowerPCCPU *cpu); void spapr_caps_add_properties(sPAPRMachineClass *smc, Error **errp); int spapr_caps_post_migration(sPAPRMachineState *spapr); +void spapr_check_pagesize(sPAPRMachineState *spapr, hwaddr pagesize, + Error **errp); + #endif /* HW_SPAPR_H */ diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 50b5d01432..9cfbd388ad 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -500,26 +500,12 @@ static void kvm_fixup_page_sizes(PowerPCCPU *cpu) cpu->hash64_opts->flags &= ~PPC_HASH64_1TSEG; } } - -bool kvmppc_is_mem_backend_page_size_ok(const char *obj_path) -{ - Object *mem_obj = object_resolve_path(obj_path, NULL); - long pagesize = host_memory_backend_pagesize(MEMORY_BACKEND(mem_obj)); - - return pagesize >= max_cpu_page_size; -} - #else /* defined (TARGET_PPC64) */ static inline void kvm_fixup_page_sizes(PowerPCCPU *cpu) { } -bool kvmppc_is_mem_backend_page_size_ok(const char *obj_path) -{ - return true; -} - #endif /* !defined (TARGET_PPC64) */ unsigned long kvm_arch_vcpu_id(CPUState *cpu) diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h index a7ddb8a5d6..443fca0a4e 100644 --- a/target/ppc/kvm_ppc.h +++ b/target/ppc/kvm_ppc.h @@ -71,7 +71,6 @@ int kvmppc_resize_hpt_commit(PowerPCCPU *cpu, target_ulong flags, int shift); bool kvmppc_pvr_workaround_required(PowerPCCPU *cpu); bool kvmppc_hpt_needs_host_contiguous_pages(void); -bool kvmppc_is_mem_backend_page_size_ok(const char *obj_path); #else @@ -228,11 +227,6 @@ static inline bool kvmppc_hpt_needs_host_contiguous_pages(void) return false; } -static inline bool kvmppc_is_mem_backend_page_size_ok(const char *obj_path) -{ - return true; -} - static inline bool kvmppc_has_cap_spapr_vfio(void) { return false; From patchwork Fri Jun 22 04:24:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 933066 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="HUXAUtF3"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Blqd1k98z9s47 for ; Fri, 22 Jun 2018 14:25:49 +1000 (AEST) Received: from localhost ([::1]:59121 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDdq-0007on-Pr for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 00:25:46 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39844) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDd3-0007lk-79 for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWDd1-0003cl-8V for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:57 -0400 Received: from ozlabs.org ([203.11.71.1]:47249) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fWDd0-0003an-Hc; Fri, 22 Jun 2018 00:24:55 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41BlpQ1Zhvz9sBL; Fri, 22 Jun 2018 14:24:44 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1529641486; bh=3yGzj1my1DmrKY+VP1SfWC8fZuvEwWj1G6YqBzycQbY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HUXAUtF3M+vqIfmphHCwd/LsBK6x4BxuuoM30ZO80Q27w6nWnzuhJqRXHlLynsNJt dsS8TTLmjnjwDWOcUtRuCb70J2VMu+gHV0vB1Eeg07+MPYH7hPITqIACDY8meITJvl KVnWFGY1JlFMNMzJboxZee4fYUkNKn0WTV0LWBwM= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 22 Jun 2018 14:24:35 +1000 Message-Id: <20180622042437.14259-21-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180622042437.14259-1-david@gibson.dropbear.id.au> References: <20180622042437.14259-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 203.11.71.1 Subject: [Qemu-devel] [PATCH 21/23] target/ppc: Add ppc_hash64_filter_pagesizes() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" The paravirtualized PAPR platform sometimes needs to restrict the guest to using only some of the page sizes actually supported by the host's MMU. At the moment this is handled in KVM specific code, but for consistency we want to apply the same limitations to all accelerators. This makes a start on this by providing a helper function in the cpu code to allow platform code to remove some of the cpu's page size definitions via a caller supplied callback. Signed-off-by: David Gibson Reviewed-by: Cédric Le Goater Reviewed-by: Greg Kurz --- target/ppc/mmu-hash64.c | 59 +++++++++++++++++++++++++++++++++++++++++ target/ppc/mmu-hash64.h | 3 +++ 2 files changed, 62 insertions(+) diff --git a/target/ppc/mmu-hash64.c b/target/ppc/mmu-hash64.c index aa200cba4c..276d9015e7 100644 --- a/target/ppc/mmu-hash64.c +++ b/target/ppc/mmu-hash64.c @@ -1166,3 +1166,62 @@ const PPCHash64Options ppc_hash64_opts_POWER7 = { }, } }; + +void ppc_hash64_filter_pagesizes(PowerPCCPU *cpu, + bool (*cb)(void *, uint32_t, uint32_t), + void *opaque) +{ + PPCHash64Options *opts = cpu->hash64_opts; + int i; + int n = 0; + bool ci_largepage = false; + + assert(opts); + + n = 0; + for (i = 0; i < ARRAY_SIZE(opts->sps); i++) { + PPCHash64SegmentPageSizes *sps = &opts->sps[i]; + int j; + int m = 0; + + assert(n <= i); + + if (!sps->page_shift) { + break; + } + + for (j = 0; j < ARRAY_SIZE(sps->enc); j++) { + PPCHash64PageSize *ps = &sps->enc[j]; + + assert(m <= j); + if (!ps->page_shift) { + break; + } + + if (cb(opaque, sps->page_shift, ps->page_shift)) { + if (ps->page_shift >= 16) { + ci_largepage = true; + } + sps->enc[m++] = *ps; + } + } + + /* Clear rest of the row */ + for (j = m; j < ARRAY_SIZE(sps->enc); j++) { + memset(&sps->enc[j], 0, sizeof(sps->enc[j])); + } + + if (m) { + n++; + } + } + + /* Clear the rest of the table */ + for (i = n; i < ARRAY_SIZE(opts->sps); i++) { + memset(&opts->sps[i], 0, sizeof(opts->sps[i])); + } + + if (!ci_largepage) { + opts->flags &= ~PPC_HASH64_CI_LARGEPAGE; + } +} diff --git a/target/ppc/mmu-hash64.h b/target/ppc/mmu-hash64.h index 53dcec5b93..f11efc9cbc 100644 --- a/target/ppc/mmu-hash64.h +++ b/target/ppc/mmu-hash64.h @@ -20,6 +20,9 @@ unsigned ppc_hash64_hpte_page_shift_noslb(PowerPCCPU *cpu, void ppc_store_lpcr(PowerPCCPU *cpu, target_ulong val); void ppc_hash64_init(PowerPCCPU *cpu); void ppc_hash64_finalize(PowerPCCPU *cpu); +void ppc_hash64_filter_pagesizes(PowerPCCPU *cpu, + bool (*cb)(void *, uint32_t, uint32_t), + void *opaque); #endif /* From patchwork Fri Jun 22 04:24:36 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 933069 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="HCRxskld"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41Bltl5Flsz9s2R for ; Fri, 22 Jun 2018 14:28:31 +1000 (AEST) Received: from localhost ([::1]:59142 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDgT-0001k2-Bo for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 00:28:29 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39822) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDd2-0007lg-QE for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:58 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWDd0-0003cQ-To for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:24:56 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:54383) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fWDd0-0003ab-Ef; Fri, 22 Jun 2018 00:24:54 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41BlpP6c6qz9sB8; Fri, 22 Jun 2018 14:24:45 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1529641485; bh=+C1rwuyE9BVJq98OzSqbtEjAW8SaoMy9JV5B/R8X75k=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=HCRxskldMDKQsGYb1wVtSJx5Ahzk4Qoz91SEIxpbR1pX7MVPrWiK4rCPFfdFNr5/o Hc3Kt3EDaZwzJ+BVcSlTUtyl2UbqzpJsP6Jibvq4X2Z57w/Jzf9ncFeXYcwgzQhVOv NuJsGS+EN+71eQRVlV6A6jzWE+/9szxi4vpX+qJg= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 22 Jun 2018 14:24:36 +1000 Message-Id: <20180622042437.14259-22-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180622042437.14259-1-david@gibson.dropbear.id.au> References: <20180622042437.14259-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 Subject: [Qemu-devel] [PATCH 22/23] spapr: Limit available pagesizes to provide a consistent guest environment X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" KVM HV has some limitations (deriving from the hardware) that mean not all host-cpu supported pagesizes may be usable in the guest. At present this means that KVM guests and TCG guests may see different available page sizes even if they notionally have the same vcpu model. This is confusing and also prevents migration between TCG and KVM. This patch makes the environment consistent by always allowing the same set of pagesizes. Since we can't remove the KVM limitations, we do this by always applying the same limitations it has, even to TCG guests. Signed-off-by: David Gibson Reviewed-by: Cédric Le Goater Reviewed-by: Greg Kurz --- hw/ppc/spapr_caps.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c index 722b213d9a..62663ebdf5 100644 --- a/hw/ppc/spapr_caps.c +++ b/hw/ppc/spapr_caps.c @@ -335,6 +335,39 @@ static void cap_hpt_maxpagesize_apply(sPAPRMachineState *spapr, spapr_check_pagesize(spapr, qemu_getrampagesize(), errp); } +static bool spapr_pagesize_cb(void *opaque, uint32_t seg_pshift, + uint32_t pshift) +{ + unsigned maxshift = *((unsigned *)opaque); + + assert(pshift >= seg_pshift); + + /* Don't allow the guest to use pages bigger than the configured + * maximum size */ + if (pshift > maxshift) { + return false; + } + + /* For whatever reason, KVM doesn't allow multiple pagesizes + * within a segment, *except* for the case of 16M pages in a 4k or + * 64k segment. Always exclude other cases, so that TCG and KVM + * guests see a consistent environment */ + if ((pshift != seg_pshift) && (pshift != 24)) { + return false; + } + + return true; +} + +static void cap_hpt_maxpagesize_cpu_apply(sPAPRMachineState *spapr, + PowerPCCPU *cpu, + uint8_t val, Error **errp) +{ + unsigned maxshift = val; + + ppc_hash64_filter_pagesizes(cpu, spapr_pagesize_cb, &maxshift); +} + sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = { [SPAPR_CAP_HTM] = { .name = "htm", @@ -402,6 +435,7 @@ sPAPRCapabilityInfo capability_table[SPAPR_CAP_NUM] = { .set = spapr_cap_set_pagesize, .type = "int", .apply = cap_hpt_maxpagesize_apply, + .cpu_apply = cap_hpt_maxpagesize_cpu_apply, }, }; From patchwork Fri Jun 22 04:24:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: David Gibson X-Patchwork-Id: 933097 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.b="PDPP4PX0"; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 41BmKP5w4Lz9s0W for ; Fri, 22 Jun 2018 14:48:09 +1000 (AEST) Received: from localhost ([::1]:59249 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDzT-000705-F4 for incoming@patchwork.ozlabs.org; Fri, 22 Jun 2018 00:48:07 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40013) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fWDd7-0007q0-RZ for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:25:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fWDd4-0003ef-5r for qemu-devel@nongnu.org; Fri, 22 Jun 2018 00:25:01 -0400 Received: from ozlabs.org ([2401:3900:2:1::2]:54045) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1fWDd3-0003cb-BI; Fri, 22 Jun 2018 00:24:58 -0400 Received: by ozlabs.org (Postfix, from userid 1007) id 41BlpQ4K13z9s9m; Fri, 22 Jun 2018 14:24:45 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gibson.dropbear.id.au; s=201602; t=1529641486; bh=XPs4DnOUT4ToAEmBbnubY71bv8w40jZ+nVZ7b3AU/2U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PDPP4PX0O2v/qJqfTtMiV6dYl1KQlC0rZcEzEC2Lh+DyrCGlB3NKe1onlbrfSWbY1 wLDAiK5b7YS59Tme6QeSb11yDTbAa35uDQ0N5IcdMq/jmI87WtMOEw/gfqqG/t9x9m hRTxiW7rQsD9pxTFLVcpeu9Nm2/hlTSiTGTYKpkA= From: David Gibson To: peter.maydell@linaro.org Date: Fri, 22 Jun 2018 14:24:37 +1000 Message-Id: <20180622042437.14259-23-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180622042437.14259-1-david@gibson.dropbear.id.au> References: <20180622042437.14259-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2401:3900:2:1::2 Subject: [Qemu-devel] [PATCH 23/23] spapr: Don't rewrite mmu capabilities in KVM mode X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, aik@ozlabs.ru, qemu-devel@nongnu.org, agraf@suse.de, groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Currently during KVM initialization on POWER, kvm_fixup_page_sizes() rewrites a bunch of information in the cpu state to reflect the capabilities of the host MMU and KVM. This overwrites the information that's already there reflecting how the TCG implementation of the MMU will operate. This means that we can get guest-visibly different behaviour between KVM and TCG (and between different KVM implementations). That's bad. It also prevents migration between KVM and TCG. The pseries machine type now has filtering of the pagesizes it allows the guest to use which means it can present a consistent model of the MMU across all accelerators. So, we can now replace kvm_fixup_page_sizes() with kvm_check_mmu() which merely verifies that the expected cpu model can be faithfully handled by KVM, rather than updating the cpu model to match KVM. We call kvm_check_mmu() from the spapr cpu reset code. This is a hack: conceptually it makes more sense where fixup_page_sizes() was - in the KVM cpu init path. However, doing that would require moving the platform's pagesize filtering much earlier, which would require a lot of work making further adjustments. There wouldn't be a lot of concrete point to doing that, since the only KVM implementation which has the awkward MMU restrictions is KVM HV, which can only work with an spapr guest anyway. Signed-off-by: David Gibson Reviewed-by: Cédric Le Goater --- hw/ppc/spapr_cpu_core.c | 2 + target/ppc/kvm.c | 133 ++++++++++++++++++++-------------------- target/ppc/kvm_ppc.h | 5 ++ 3 files changed, 72 insertions(+), 68 deletions(-) diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index bfb94f650c..993759db47 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -78,6 +78,8 @@ static void spapr_cpu_reset(void *opaque) spapr_cpu->dtl_size = 0; spapr_caps_cpu_apply(SPAPR_MACHINE(qdev_get_machine()), cpu); + + kvm_check_mmu(cpu, &error_fatal); } void spapr_cpu_set_entry_state(PowerPCCPU *cpu, target_ulong nip, target_ulong r3) diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 9cfbd388ad..4df4ff6cbf 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -419,93 +419,93 @@ bool kvmppc_hpt_needs_host_contiguous_pages(void) return !!(smmu_info.flags & KVM_PPC_PAGE_SIZES_REAL); } -static bool kvm_valid_page_size(uint32_t flags, long rampgsize, uint32_t shift) +void kvm_check_mmu(PowerPCCPU *cpu, Error **errp) { - if (!kvmppc_hpt_needs_host_contiguous_pages()) { - return true; - } - - return (1ul << shift) <= rampgsize; -} - -static long max_cpu_page_size; - -static void kvm_fixup_page_sizes(PowerPCCPU *cpu) -{ - static struct kvm_ppc_smmu_info smmu_info; - static bool has_smmu_info; - CPUPPCState *env = &cpu->env; + struct kvm_ppc_smmu_info smmu_info; int iq, ik, jq, jk; - /* We only handle page sizes for 64-bit server guests for now */ - if (!(env->mmu_model & POWERPC_MMU_64)) { + /* For now, we only have anything to check on hash64 MMUs */ + if (!cpu->hash64_opts || !kvm_enabled()) { return; } - /* Collect MMU info from kernel if not already */ - if (!has_smmu_info) { - kvm_get_smmu_info(cpu, &smmu_info); - has_smmu_info = true; - } + kvm_get_smmu_info(cpu, &smmu_info); - if (!max_cpu_page_size) { - max_cpu_page_size = qemu_getrampagesize(); + if (ppc_hash64_has(cpu, PPC_HASH64_1TSEG) + && !(smmu_info.flags & KVM_PPC_1T_SEGMENTS)) { + error_setg(errp, + "KVM does not support 1TiB segments which guest expects"); + return; } - /* Convert to QEMU form */ - memset(cpu->hash64_opts->sps, 0, sizeof(*cpu->hash64_opts->sps)); - - /* If we have HV KVM, we need to forbid CI large pages if our - * host page size is smaller than 64K. - */ - if (kvmppc_hpt_needs_host_contiguous_pages()) { - if (getpagesize() >= 0x10000) { - cpu->hash64_opts->flags |= PPC_HASH64_CI_LARGEPAGE; - } else { - cpu->hash64_opts->flags &= ~PPC_HASH64_CI_LARGEPAGE; - } + if (smmu_info.slb_size < cpu->hash64_opts->slb_size) { + error_setg(errp, "KVM only supports %u SLB entries, but guest needs %u", + smmu_info.slb_size, cpu->hash64_opts->slb_size); + return; } /* - * XXX This loop should be an entry wide AND of the capabilities that - * the selected CPU has with the capabilities that KVM supports. + * Verify that every pagesize supported by the cpu model is + * supported by KVM with the same encodings */ - for (ik = iq = 0; ik < KVM_PPC_PAGE_SIZES_MAX_SZ; ik++) { + for (iq = 0; iq < ARRAY_SIZE(cpu->hash64_opts->sps); iq++) { PPCHash64SegmentPageSizes *qsps = &cpu->hash64_opts->sps[iq]; - struct kvm_ppc_one_seg_page_size *ksps = &smmu_info.sps[ik]; + struct kvm_ppc_one_seg_page_size *ksps; - if (!kvm_valid_page_size(smmu_info.flags, max_cpu_page_size, - ksps->page_shift)) { - continue; - } - qsps->page_shift = ksps->page_shift; - qsps->slb_enc = ksps->slb_enc; - for (jk = jq = 0; jk < KVM_PPC_PAGE_SIZES_MAX_SZ; jk++) { - if (!kvm_valid_page_size(smmu_info.flags, max_cpu_page_size, - ksps->enc[jk].page_shift)) { - continue; - } - qsps->enc[jq].page_shift = ksps->enc[jk].page_shift; - qsps->enc[jq].pte_enc = ksps->enc[jk].pte_enc; - if (++jq >= PPC_PAGE_SIZES_MAX_SZ) { + for (ik = 0; ik < ARRAY_SIZE(smmu_info.sps); ik++) { + if (qsps->page_shift == smmu_info.sps[ik].page_shift) { break; } } - if (++iq >= PPC_PAGE_SIZES_MAX_SZ) { - break; + if (ik >= ARRAY_SIZE(smmu_info.sps)) { + error_setg(errp, "KVM doesn't support for base page shift %u", + qsps->page_shift); + return; + } + + ksps = &smmu_info.sps[ik]; + if (ksps->slb_enc != qsps->slb_enc) { + error_setg(errp, +"KVM uses SLB encoding 0x%x for page shift %u, but guest expects 0x%x", + ksps->slb_enc, ksps->page_shift, qsps->slb_enc); + return; + } + + for (jq = 0; jq < ARRAY_SIZE(qsps->enc); jq++) { + for (jk = 0; jk < ARRAY_SIZE(ksps->enc); jk++) { + if (qsps->enc[jq].page_shift == ksps->enc[jk].page_shift) { + break; + } + } + + if (jk >= ARRAY_SIZE(ksps->enc)) { + error_setg(errp, "KVM doesn't support page shift %u/%u", + qsps->enc[jq].page_shift, qsps->page_shift); + return; + } + if (qsps->enc[jq].pte_enc != ksps->enc[jk].pte_enc) { + error_setg(errp, +"KVM uses PTE encoding 0x%x for page shift %u/%u, but guest expects 0x%x", + ksps->enc[jk].pte_enc, qsps->enc[jq].page_shift, + qsps->page_shift, qsps->enc[jq].pte_enc); + return; + } } } - cpu->hash64_opts->slb_size = smmu_info.slb_size; - if (!(smmu_info.flags & KVM_PPC_1T_SEGMENTS)) { - cpu->hash64_opts->flags &= ~PPC_HASH64_1TSEG; - } -} -#else /* defined (TARGET_PPC64) */ -static inline void kvm_fixup_page_sizes(PowerPCCPU *cpu) -{ + if (ppc_hash64_has(cpu, PPC_HASH64_CI_LARGEPAGE)) { + /* Mostly what guest pagesizes we can use are related to the + * host pages used to map guest RAM, which is handled in the + * platform code. Cache-Inhibited largepages (64k) however are + * used for I/O, so if they're mapped to the host at all it + * will be a normal mapping, not a special hugepage one used + * for RAM. */ + if (getpagesize() < 0x10000) { + error_setg(errp, + "KVM can't supply 64kiB CI pages, which guest expects"); + } + } } - #endif /* !defined (TARGET_PPC64) */ unsigned long kvm_arch_vcpu_id(CPUState *cpu) @@ -551,9 +551,6 @@ int kvm_arch_init_vcpu(CPUState *cs) CPUPPCState *cenv = &cpu->env; int ret; - /* Gather server mmu info from KVM and update the CPU state */ - kvm_fixup_page_sizes(cpu); - /* Synchronize sregs with kvm */ ret = kvm_arch_sync_sregs(cpu); if (ret) { diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h index 443fca0a4e..657582bb32 100644 --- a/target/ppc/kvm_ppc.h +++ b/target/ppc/kvm_ppc.h @@ -71,6 +71,7 @@ int kvmppc_resize_hpt_commit(PowerPCCPU *cpu, target_ulong flags, int shift); bool kvmppc_pvr_workaround_required(PowerPCCPU *cpu); bool kvmppc_hpt_needs_host_contiguous_pages(void); +void kvm_check_mmu(PowerPCCPU *cpu, Error **errp); #else @@ -227,6 +228,10 @@ static inline bool kvmppc_hpt_needs_host_contiguous_pages(void) return false; } +static inline void kvm_check_mmu(PowerPCCPU *cpu, Error **errp) +{ +} + static inline bool kvmppc_has_cap_spapr_vfio(void) { return false;