From patchwork Thu Mar 8 16:54:21 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Igor Mammedov X-Patchwork-Id: 145573 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id ECD2CB6F98 for ; Fri, 9 Mar 2012 03:54:48 +1100 (EST) Received: from localhost ([::1]:59557 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S5gc2-0008Hj-UQ for incoming@patchwork.ozlabs.org; Thu, 08 Mar 2012 11:54:46 -0500 Received: from eggs.gnu.org ([208.118.235.92]:34549) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S5gbr-0008Gi-Dq for qemu-devel@nongnu.org; Thu, 08 Mar 2012 11:54:41 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1S5gbj-0000Dy-0v for qemu-devel@nongnu.org; Thu, 08 Mar 2012 11:54:34 -0500 Received: from mx1.redhat.com ([209.132.183.28]:47082) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S5gbi-0000Dh-OX for qemu-devel@nongnu.org; Thu, 08 Mar 2012 11:54:26 -0500 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q28GsOrT027803 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 8 Mar 2012 11:54:24 -0500 Received: from nial.brq.redhat.com (dhcp-1-247.brq.redhat.com [10.34.1.247]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q28GsMY4007690; Thu, 8 Mar 2012 11:54:22 -0500 From: Igor Mammedov To: seabios@seabios.org Date: Thu, 8 Mar 2012 17:54:21 +0100 Message-Id: <1331225661-23630-1-git-send-email-imammedo@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: jan.kiszka@siemens.com, qemu-devel@nongnu.org, gleb@redhat.com Subject: [Qemu-devel] [RFC] [SEABIOS] Take in account hotplugged cpus on reboot X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Initial count of active cpus is communicated to bios from qemu via CMOS_BIOS_SMP_COUNT io port. However if cpus are hotplugged after boot and then guest is rebooted without taking down qemu then bios might be stuck at smp_probe while (cmos_smp_count + 1 != readl(&CountCPUs)) yield(); where cmos_smp_count + 1 will be less that CountCPUs due to additional hotplugged cpus. One way to fix bug is to take in account hotplugged cpus and count online cpus in cpu status bitmap that qemu provides at 0xaf00 and bios uses for ACPI cpu hotplug in acpi-dsdt.dsl. Alternative ways to fix issue is disscussed on following thread: http://www.seabios.org/pipermail/seabios/2011-August/002147.html without any conclusion Rationale why counting cpus in cpu_sts bitmap at 0xaf00 might be better that updating CMOS_BIOS_SMP_COUNT in qemu. feeble one: we already relying on cpu_sts at 0xaf00 for ACPI cpu hotplug machinery and it seems that there is no standard way to pass this info (so we are now using "board extension"). 2nd: another possible use for cpu_sts bitmap is when cpus are able to be (hot)plugged in nonconsecutive order, MADT + CPON package should be build taking in account info about which cpus are (un)plugged. However there is compatibility question: What to do with qemu versions that doen't have cpu_hotplug? --- src/smp.c | 18 ++++++++++++++++++ 1 files changed, 18 insertions(+), 0 deletions(-) diff --git a/src/smp.c b/src/smp.c index 8c077a1..f24d6fa 100644 --- a/src/smp.c +++ b/src/smp.c @@ -17,6 +17,9 @@ #define APIC_ENABLED 0x0100 +#define ACPI_CPU_STATUS_MAP 0xaf00 +#define ACPI_CPU_STATUS_MAP_SZ 32 + struct { u32 ecx, eax, edx; } smp_mtrr[32] VAR16VISIBLE; u32 smp_mtrr_count VAR16VISIBLE; @@ -115,6 +118,21 @@ smp_probe(void) msleep(10); } else { u8 cmos_smp_count = inb_cmos(CMOS_BIOS_SMP_COUNT); + u8 i = 0, acpi_cpu_online_count = 0; + + /* count plugged in cpus in acpi PRST bitmap */ + while (i < ACPI_CPU_STATUS_MAP_SZ) { + u8 j = 0, status = inb(ACPI_CPU_STATUS_MAP + (i++)); + while (j < 8) + if ((status >> j++) & 1) + ++acpi_cpu_online_count; + } + /* if one or several cpus were hotplugged then on reboot we should + * take them into account and wait for them too*/ + if (cmos_smp_count < --acpi_cpu_online_count) + cmos_smp_count = acpi_cpu_online_count; + + dprintf(1, "acpi_cpu_online_count: %d\n", acpi_cpu_online_count); while (cmos_smp_count + 1 != readl(&CountCPUs)) yield(); }