From patchwork Sat Jun 13 21:36:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Salil Mehta X-Patchwork-Id: 187910 Delivered-To: patch@linaro.org Received: by 2002:a92:cf06:0:0:0:0:0 with SMTP id c6csp1524505ilo; Sat, 13 Jun 2020 14:56:29 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyBPQUYvtdFVvQwCp54BhWcPnv0qI8gamZv3Uo5WE0Hfw7UX9GUwIKBr7/Q6fk7Y7Lh0Y/v X-Received: by 2002:a25:941:: with SMTP id u1mr34746072ybm.274.1592085389301; Sat, 13 Jun 2020 14:56:29 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1592085389; cv=none; d=google.com; s=arc-20160816; b=SwrTd9FbqIYtENaeBPPyFP/1h/B7Rz3ZUv749wR//AOhkebOgOcZ2VJOudO6aeSzvH lMl5c5lq8j7GZWTz3tkukTv//rNsCuRo/xwEIzX1GecgHFPe25bedD/lCr0JDSblD4Zm sjd5oXjXA0TviqC3LXVUfrHaP+HyQasKwq3MLZmQuGuOyAEuzlkj8g51WrFgL7CC8HnW VVt+s86v7+cYNF0+WvwsAGNDC45Ry1Yc+CJlhdLgirCgQhdfSdUPRlh4s47NFRc9cGGb 7mhevl7pLAiSsNW8569K3DaAUv5pLRv1K5TiN0VHWEcFVLB3crWqCIL22tsEh3hK9Dp+ ou9Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:mime-version:references :in-reply-to:message-id:date:subject:to:from; bh=p8f2316/5VSDlnkLsjAR4bYn/6sfpOsqMa3xuXFRUoM=; b=ZGVIDOJSDMGrsTWIuH5Uo0QrqrhH7XGVUBzG0C76ekToVq9k7BLvUBvoyPfo+ZWuGS +JLO2sDyDW3qhUW2sWgeW8gvN39w2xd4n2GLofZnwK7nPrYQPK5hnkVB6a5vAYINWDPs JZBbjsUkm743f9uYZTalHNPpjd/cUKIA0cmSNYkcLfyl92DMpnK4RHsY4gLSG37Te1kM +OjZ6X1l4nU7xHIgoOzq6DGGDrXzArQjFZ3n50FlC5Agg5eh6QCB/r2TKxIfbb9QsjuT ogqX93OnA1sZlCxgHS5E9dXB77EmMXNUdeHUUpMbwuZckDxux0tsMXx6u4FpW7Q5bo1G k7rA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org" Return-Path: Received: from lists.gnu.org (lists.gnu.org. [209.51.188.17]) by mx.google.com with ESMTPS id e67si8696766ybc.346.2020.06.13.14.56.29 for (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Sat, 13 Jun 2020 14:56:29 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom="qemu-devel-bounces+patch=linaro.org@nongnu.org" Received: from localhost ([::1]:44356 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jkE8a-000084-QC for patch@linaro.org; Sat, 13 Jun 2020 17:56:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:60472) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jkDyY-0007XF-IW; Sat, 13 Jun 2020 17:46:06 -0400 Received: from szxga04-in.huawei.com ([45.249.212.190]:3709 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jkDyW-0003SP-1z; Sat, 13 Jun 2020 17:46:06 -0400 Received: from DGGEMS406-HUB.china.huawei.com (unknown [172.30.72.59]) by Forcepoint Email with ESMTP id 7C39C247F741223B5826; Sun, 14 Jun 2020 05:46:01 +0800 (CST) Received: from A190218597.china.huawei.com (10.47.30.60) by DGGEMS406-HUB.china.huawei.com (10.3.19.206) with Microsoft SMTP Server id 14.3.487.0; Sun, 14 Jun 2020 05:45:52 +0800 From: Salil Mehta To: , Subject: [PATCH RFC 17/22] arm/cpuhp: Changes to (un)wire GICC<->VCPU IRQs during hot-(un)plug Date: Sat, 13 Jun 2020 22:36:24 +0100 Message-ID: <20200613213629.21984-18-salil.mehta@huawei.com> X-Mailer: git-send-email 2.8.3 In-Reply-To: <20200613213629.21984-1-salil.mehta@huawei.com> References: <20200613213629.21984-1-salil.mehta@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.47.30.60] X-CFilter-Loop: Reflected Received-SPF: pass client-ip=45.249.212.190; envelope-from=salil.mehta@huawei.com; helo=huawei.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/13 17:44:30 X-ACL-Warn: Detected OS = Linux 3.11 and newer [fuzzy] X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H4=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, drjones@redhat.com, sudeep.holla@arm.com, gshan@redhat.com, mst@redhat.com, jiakernel2@gmail.com, maz@kernel.org, zhukeqian1@huawei.com, david@redhat.com, richard.henderson@linaro.org, linuxarm@huawei.com, eric.auger@redhat.com, james.morse@arm.com, catalin.marinas@arm.com, imammedo@redhat.com, Salil Mehta , pbonzini@redhat.com, mehta.salil.lnk@gmail.com, maran.wilson@oracle.com, will@kernel.org, wangxiongfeng2@huawei.com Errors-To: qemu-devel-bounces+patch=linaro.org@nongnu.org Sender: "Qemu-devel" Refactors the existing gic create code to extract common code to wire the vcpu<->gic interrupts. This function could be used with cold-plug case and also used when vcpu is hot-plugged. It also introduces a new function to unwire the vcpu>->gic interrupts for the vcpu hot-unplug cases. Co-developed-by: Keqian Zhu Signed-off-by: Salil Mehta --- hw/arm/virt.c | 144 +++++++++++++++++++++++++++++------------ hw/core/qdev.c | 2 +- include/hw/qdev-core.h | 2 + 3 files changed, 104 insertions(+), 44 deletions(-) -- 2.17.1 diff --git a/hw/arm/virt.c b/hw/arm/virt.c index ac2941159a..f0295e940e 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -615,6 +615,103 @@ static void create_v2m(VirtMachineState *vms) fdt_add_v2m_gic_node(vms); } +static void unwire_gic_cpu_irqs(VirtMachineState *vms, CPUState *cs) +{ + unsigned int max_cpus = vms->max_cpus; + DeviceState *cpudev = DEVICE(cs); + DeviceState *gicdev = vms->gic; + int cpu = CPU(cs)->cpu_index; + int type = vms->gic_version; + int irq; + + /* Mapping from the output timer irq lines from the CPU to the + * GIC PPI inputs we use for the virt board. + */ + const int timer_irq[] = { + [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ, + [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ, + [GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ, + [GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ, + }; + + for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) { + qdev_disconnect_gpio_out_named(cpudev, NULL, irq); + } + + if (type == 3) { + qdev_disconnect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", 0); + } else if (vms->virt) { + qdev_disconnect_gpio_out_named(gicdev, SYSBUS_DEVICE_GPIO_IRQ, cpu + 4 * max_cpus); + } + + /* + * RFC: Question: This currently does not takes care of intimating the devices + * which might be sitting on system bus. Do we need a sysbus_disconnect_irq() + * which also does the job of notification beside disconnection? + */ + qdev_disconnect_gpio_out_named(cpudev, "pmu-interrupt", 0); + qdev_disconnect_gpio_out_named(gicdev, SYSBUS_DEVICE_GPIO_IRQ, cpu); + qdev_disconnect_gpio_out_named(gicdev, + SYSBUS_DEVICE_GPIO_IRQ, cpu + max_cpus); + qdev_disconnect_gpio_out_named(gicdev, SYSBUS_DEVICE_GPIO_IRQ, + cpu + 2 * max_cpus); + qdev_disconnect_gpio_out_named(gicdev, SYSBUS_DEVICE_GPIO_IRQ, + cpu + 3 * max_cpus); +} + +static void wire_gic_cpu_irqs(VirtMachineState *vms, CPUState *cs) +{ + unsigned int max_cpus = vms->max_cpus; + DeviceState *cpudev = DEVICE(cs); + DeviceState *gicdev = vms->gic; + int cpu = CPU(cs)->cpu_index; + int type = vms->gic_version; + SysBusDevice *gicbusdev; + int ppibase; + int irq; + + ppibase = NUM_IRQS + cpu * GIC_INTERNAL + GIC_NR_SGIS; + + /* Mapping from the output timer irq lines from the CPU to the + * GIC PPI inputs we use for the virt board. + */ + const int timer_irq[] = { + [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ, + [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ, + [GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ, + [GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ, + }; + + for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) { + qdev_connect_gpio_out(cpudev, irq, + qdev_get_gpio_in(gicdev, + ppibase + timer_irq[irq])); + } + + gicbusdev = SYS_BUS_DEVICE(gicdev); + if (type == 3) { + qemu_irq irq = qdev_get_gpio_in(gicdev, + ppibase + ARCH_GIC_MAINT_IRQ); + qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", + 0, irq); + } else if (vms->virt) { + qemu_irq irq = qdev_get_gpio_in(gicdev, + ppibase + ARCH_GIC_MAINT_IRQ); + sysbus_connect_irq(gicbusdev, cpu + 4 * max_cpus, irq); + } + + qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0, + qdev_get_gpio_in(gicdev, + ppibase + VIRTUAL_PMU_IRQ)); + sysbus_connect_irq(gicbusdev, cpu, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ)); + sysbus_connect_irq(gicbusdev, cpu + max_cpus, + qdev_get_gpio_in(cpudev, ARM_CPU_FIQ)); + sysbus_connect_irq(gicbusdev, cpu + 2 * max_cpus, + qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ)); + sysbus_connect_irq(gicbusdev, cpu + 3 * max_cpus, + qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ)); +} + static void create_gic(VirtMachineState *vms) { /* We create a standalone GIC */ @@ -684,47 +781,7 @@ static void create_gic(VirtMachineState *vms) * and the GIC's IRQ/FIQ/VIRQ/VFIQ interrupt outputs to the CPU's inputs. */ for (i = 0; i < smp_cpus; i++) { - DeviceState *cpudev = DEVICE(qemu_get_cpu(i)); - int ppibase = NUM_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS; - int irq; - /* Mapping from the output timer irq lines from the CPU to the - * GIC PPI inputs we use for the virt board. - */ - const int timer_irq[] = { - [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ, - [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ, - [GTIMER_HYP] = ARCH_TIMER_NS_EL2_IRQ, - [GTIMER_SEC] = ARCH_TIMER_S_EL1_IRQ, - }; - - for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) { - qdev_connect_gpio_out(cpudev, irq, - qdev_get_gpio_in(vms->gic, - ppibase + timer_irq[irq])); - } - - if (type == 3) { - qemu_irq irq = qdev_get_gpio_in(vms->gic, - ppibase + ARCH_GIC_MAINT_IRQ); - qdev_connect_gpio_out_named(cpudev, "gicv3-maintenance-interrupt", - 0, irq); - } else if (vms->virt) { - qemu_irq irq = qdev_get_gpio_in(vms->gic, - ppibase + ARCH_GIC_MAINT_IRQ); - sysbus_connect_irq(gicbusdev, i + 4 * max_cpus, irq); - } - - qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0, - qdev_get_gpio_in(vms->gic, ppibase - + VIRTUAL_PMU_IRQ)); - - sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ)); - sysbus_connect_irq(gicbusdev, i + max_cpus, - qdev_get_gpio_in(cpudev, ARM_CPU_FIQ)); - sysbus_connect_irq(gicbusdev, i + 2 * max_cpus, - qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ)); - sysbus_connect_irq(gicbusdev, i + 3 * max_cpus, - qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ)); + wire_gic_cpu_irqs(vms, qemu_get_cpu(i)); } fdt_add_gic_node(vms); @@ -2382,6 +2439,7 @@ static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, static void virt_cpu_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { + VirtMachineState *vms = VIRT_MACHINE(hotplug_dev); MachineState *ms = MACHINE(hotplug_dev); ARMCPU *cpu = ARM_CPU(dev); CPUState *cs = CPU(dev); @@ -2392,7 +2450,7 @@ static void virt_cpu_plug(HotplugHandler *hotplug_dev, DeviceState *dev, cpu_slot->cpu = OBJECT(dev); if (dev->hotplugged) { - /* TODO: wire the gic-cpu irqs */ + wire_gic_cpu_irqs(vms, cs); /* TODO: update acpi hotplug state and send cpu hotplug event to guest */ /* TODO: register this cpu for reset & update F/W info for the next boot */ } @@ -2447,7 +2505,7 @@ static void virt_cpu_unplug(HotplugHandler *hotplug_dev, DeviceState *dev, /* TODO: update the acpi cpu hotplug state for cpu hot-unplug */ - /* TODO: unwire the gic-cpu irqs here */ + unwire_gic_cpu_irqs(vms, cs); /* TODO: update the GIC about this hot unplug change */ /* TODO: unregister this cpu for reset & update F/W info for the next boot */ diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 9e5538aeae..65b3ec7c8f 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -563,7 +563,7 @@ qemu_irq qdev_get_gpio_out_connector(DeviceState *dev, const char *name, int n) /* disconnect a GPIO output, returning the disconnected input (if any) */ -static qemu_irq qdev_disconnect_gpio_out_named(DeviceState *dev, +qemu_irq qdev_disconnect_gpio_out_named(DeviceState *dev, const char *name, int n) { char *propname = g_strdup_printf("%s[%d]", diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h index b870b27966..8434cc5a3e 100644 --- a/include/hw/qdev-core.h +++ b/include/hw/qdev-core.h @@ -355,6 +355,8 @@ void qdev_connect_gpio_out_named(DeviceState *dev, const char *name, int n, qemu_irq qdev_get_gpio_out_connector(DeviceState *dev, const char *name, int n); qemu_irq qdev_intercept_gpio_out(DeviceState *dev, qemu_irq icpt, const char *name, int n); +qemu_irq qdev_disconnect_gpio_out_named(DeviceState *dev, + const char *name, int n); BusState *qdev_get_child_bus(DeviceState *dev, const char *name);