From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from userp2120.oracle.com (userp2120.oracle.com [156.151.31.85]) by mx.groups.io with SMTP id smtpd.web10.6069.1613725501373003584 for ; Fri, 19 Feb 2021 01:05:01 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@oracle.com header.s=corp-2020-01-29 header.b=w2A0fHpW; spf=pass (domain: oracle.com, ip: 156.151.31.85, mailfrom: ankur.a.arora@oracle.com) Received: from pps.filterd (userp2120.oracle.com [127.0.0.1]) by userp2120.oracle.com (8.16.0.42/8.16.0.42) with SMTP id 11J94Fvb111119; Fri, 19 Feb 2021 09:04:58 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : content-transfer-encoding : content-type : mime-version; s=corp-2020-01-29; bh=LRmSgHeU2Z8fSi2Ls38i75CZGzgGp6EbcgbHjRODjIU=; b=w2A0fHpWPBLOQC1SD5ZowyrXl3qz2m3rgBKplpPvZCPn9J30lT46ujpD6ZKpu4G0KqNL 8elXOwgXGRJCeaTPNgrv2SfivfAQNF5r+K3HV4Sc870gYx41GL8qv3Cv2PtUPIuOr6d1 y2CcxyhgJtVVWr2yccx+plN83U4/ugx43s4ttOMffwI6TOXEBB0S71v5UaeF8glaMpFC 6X4MIzIOh0xi0b+3cML//kuA80bxz4FgaDZzKl4vvINNxIO+9fZVDxI0FdAySqpQfBeI qMZBt+i9aWX23l6w58bn+g0fneMXlZyf7q/jO0HM1ho2M8X8hZEAMTR6wY8l7YAzccHE 7g== Received: from userp3020.oracle.com (userp3020.oracle.com [156.151.31.79]) by userp2120.oracle.com with ESMTP id 36p7dnrn7h-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 19 Feb 2021 09:04:58 +0000 Received: from pps.filterd (userp3020.oracle.com [127.0.0.1]) by userp3020.oracle.com (8.16.0.42/8.16.0.42) with SMTP id 11J8tl0s182210; Fri, 19 Feb 2021 09:04:58 GMT Received: from nam12-bn8-obe.outbound.protection.outlook.com (mail-bn8nam12lp2177.outbound.protection.outlook.com [104.47.55.177]) by userp3020.oracle.com with ESMTP id 36prhve0ju-3 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 19 Feb 2021 09:04:57 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=krsszLS2JIyf/JmUhymkojMC0vPSPz/7205Z4rf5GFlJg9gd1rqfTtDcBB1PkmmgCTUiHMlFQGujsh7ClNjXRqQqZTZDQJ05n+ZDFKvcs8Dxlu4+A91gsnVDQO9JxpPKnoGdcp0IT+qocMcmwAPVnVC+nxUilweJCLkLdA8n+p1ogGSLGcmN+dlE/fwlxx7ytDgBgugOLHRMYjYGdhiCJcuXx5sUpRTx4uG1ltW+JkWi+kuVuWXYWLqm1NJvJQKk4QjFGhx7n3b8RZPWS/35QQmqEmJVqlCmOOGxtyR/XD68TzWXdrFp4l2lMt8G+ZwTXSBxQC99vz3nHfepiesmEQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=LRmSgHeU2Z8fSi2Ls38i75CZGzgGp6EbcgbHjRODjIU=; b=OMGaxWd1RoojsEPKaoxxLGBPOqwDAsRCSCGyCkMN5Ugc6rj5npa9+yYC9CxAhUXTwXecsLxG9wkMrgnQYqLSu2hNq079fngtWRiDbgnj3/4zOBceYIBOjAfygL2aa+26yyA2fKqJX9E/yJFoIDLuvJZjKuPWPvpyKnRNpatgIv4wvPEE4Anmrlvsffv8001GhfbXsWVGU98NThrb4i1DRcCdjRxfebPQ3PsPwS15CZh0mqJp2u6PdLGxURMovuB1BxP+UdvwaicuqseMqhBEtZiw9E47M9uUzM8gyMvZPGLUuWEr4eUE+xrPEH8pgevWvzwQNjvXh9p6qeHqQY9oCQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oracle.com; dmarc=pass action=none header.from=oracle.com; dkim=pass header.d=oracle.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.onmicrosoft.com; s=selector2-oracle-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=LRmSgHeU2Z8fSi2Ls38i75CZGzgGp6EbcgbHjRODjIU=; b=eMi1wxNEs2mpdIWMTgVT3qbN7Y27kVjB8FsBA3TTsIdGAWUHGBphRm1H52LlbyXYGPaePZPwVK7oa2RdWLNi+L+KNzE9B/xvY5oa5+TNkAPU884Z3TR1NOsGIHCpbDpcpjB7HHzwtZflkjsPbYsVL/iXYySSFjMu/Y/5g2Hh0mg= Authentication-Results: edk2.groups.io; dkim=none (message not signed) header.d=none;edk2.groups.io; dmarc=none action=none header.from=oracle.com; Received: from SJ0PR10MB4605.namprd10.prod.outlook.com (2603:10b6:a03:2d9::24) by BYAPR10MB3605.namprd10.prod.outlook.com (2603:10b6:a03:129::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3846.27; Fri, 19 Feb 2021 09:04:56 +0000 Received: from SJ0PR10MB4605.namprd10.prod.outlook.com ([fe80::a021:790:7ce6:6f16]) by SJ0PR10MB4605.namprd10.prod.outlook.com ([fe80::a021:790:7ce6:6f16%6]) with mapi id 15.20.3868.029; Fri, 19 Feb 2021 09:04:56 +0000 From: "Ankur Arora" To: devel@edk2.groups.io Cc: lersek@redhat.com, imammedo@redhat.com, boris.ostrovsky@oracle.com, Ankur Arora , Jordan Justen , Ard Biesheuvel , Aaron Young Subject: [PATCH v7 02/10] OvmfPkg/CpuHotplugSmm: collect hot-unplug events Date: Fri, 19 Feb 2021 01:04:36 -0800 Message-Id: <20210219090444.1332380-3-ankur.a.arora@oracle.com> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210219090444.1332380-1-ankur.a.arora@oracle.com> References: <20210219090444.1332380-1-ankur.a.arora@oracle.com> X-Originating-IP: [148.87.23.5] X-ClientProxiedBy: MWHPR13CA0004.namprd13.prod.outlook.com (2603:10b6:300:16::14) To SJ0PR10MB4605.namprd10.prod.outlook.com (2603:10b6:a03:2d9::24) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from prion.us.oracle.com (148.87.23.5) by MWHPR13CA0004.namprd13.prod.outlook.com (2603:10b6:300:16::14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3890.8 via Frontend Transport; Fri, 19 Feb 2021 09:04:55 +0000 X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 191fa47a-41ac-40e2-829b-08d8d4b56d4a X-MS-TrafficTypeDiagnostic: BYAPR10MB3605: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:9508; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: Fo1i1XSdmvC6zbaXGKygZIo/pPbeW3aMPKRlIwjZpovVLgB1zD9PJUMq89qxjlXDTOPtappUSnHLsfZ2ZzLdfYMLhVdvXcjDiq/ivR9PO/t7Hjb8wd25k6Q2c+YO7rU3v7CTTjGYVGPufOXzyCnfuML/SqSHL3T1VFoYrhGu1YtNq1sbSerAMdpTAh3ZO6nB9mm2IAUBdYee+doniYytSfIwKi5m+LJisTbp9sNZDQvm5St9kkpwpElO8jv0yBRPLbpFdhhopXlRwVSdCSN2O22spfSpMcukAAPD3oEcScrZMHI7FMpub97BsRjKCx5Nemo+6vYanxyhyOgrh3Jy9Pc+3hms7G19aYN0sz+wphtmosXX/060ttNCv/1jOwYH/D0oHQzoeszm5fznSnpBsL1Ee8CiOCtC3UlDDyZFp1dr53WAuMuljI+Ubtt4LIz4usM0X9UiKz6ZQIdazxHtJA8r+EkKI1fvIYuW0v71Y0lRK+jaICKYsYSTiPD1O0yyfNEIAMFXBFkCTp3yNib6YIbf+VV3wRH31wKaEIl2Ibmdwb9EY0zIlI7GRej8Wv/lAliqwSm3/00w1zM2x/54HSuvLd1QSWWUZyMPQnLUk58= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SJ0PR10MB4605.namprd10.prod.outlook.com;PTR:;CAT:NONE;SFS:(366004)(376002)(39860400002)(346002)(396003)(136003)(83380400001)(7696005)(66946007)(2616005)(66556008)(6486002)(36756003)(86362001)(316002)(6666004)(54906003)(966005)(8676002)(66476007)(52116002)(478600001)(956004)(4326008)(5660300002)(6916009)(8936002)(2906002)(107886003)(1076003)(186003)(103116003)(26005)(16526019);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData: =?us-ascii?Q?tONmShFZJlpjntvJei9/nbpcfN15GOezPbZRNpE/26+FoSUOX3bekLc+T9K8?= =?us-ascii?Q?yzzaUShZZqzVWZxqrCXoSrD6CHJuM0gGoj3KQWAoGmeb25HMzWvS7LZoe5Uk?= =?us-ascii?Q?MlwcAGJNpVZ1ouyIbU0O3sgZDpHqYU6ZSFBVGaXmcm9zdtCAy1lpt4Y/C+AO?= =?us-ascii?Q?QSU7F4+otlVjeYMzeYQD5FThXSAdy3ehH5M2KPRiPiE834QLc0JCxedkcI6y?= =?us-ascii?Q?GIl4ICjw9qvD+E+xplVUihZUqbdKF/K8Y1V8I3LvSpGu4qsYCdXWZjRRqO6E?= =?us-ascii?Q?cJCi9Z7Ydpa3jNFi9M5oHRhdbD76Tn7czNCY0nLw8RP+FA1TM31UIDO8zUHT?= =?us-ascii?Q?CXy3n6Jehvp+I+06NcJfKAC+JUrV/ehWt+GweBQfd2ZYf0yiSj5HRkbBnDWr?= =?us-ascii?Q?RN4MzZ6UUMfAA7K7QqZ7n9zRTNdrF0ISoE37vioYwyPQSart+1VuIR+IxG+g?= =?us-ascii?Q?Xv1n3NvE8JL+5Mred4fnx5ORjafK7wNHs5bAB+F632wNor2dSpzQmHr/pVPw?= =?us-ascii?Q?UX8rXkXBURebxuLJpGNNPp4J7Waf66kX3r5p8IRvMESkDpp9U0OxGeXMcpIh?= =?us-ascii?Q?o5EHOXH9hBgU4wgk2Zl4ekIwZlDZkaKqGtjeTnT7ClfvMDrMIArg0RA8JkH0?= =?us-ascii?Q?wmwGH85P43XlLq+3AZLVyJkg6C/aPswBuBopulc6651Nv8Il7tNulXepb2BK?= =?us-ascii?Q?/xc8emajmTtDxcTgYvQo9LfGKiK5tZhvXFOLqQTReOSSY4yNVwl6mJH7BGTA?= =?us-ascii?Q?Hvh70a8g4k0Xvg6ZSGT/o8wxX9dgUWjxA3jUI04+9++DtpTNAkEUVijkK0P9?= =?us-ascii?Q?WkyKSlGnYRyV8EpN93xplNVWCwxHxBOm+SPN3ruj8vGguPRwnC0l/IZiVdfC?= =?us-ascii?Q?hioSv4ANKJkJYkOE61E5cKmzNK9oruRIB/zPt9r4swxcSycr8BLsjjqiV2Wq?= =?us-ascii?Q?J7MHd5uK/lT0IqTmocdaqyE0Et29I6urUOk3kZu/RNCsnnFVMiyueNFmfQeS?= =?us-ascii?Q?yLYocvDqOUO0yCRzFj3KW30aF1kgcE+UUel6+yMhqAe8hoA/VSHYh0L8DkJN?= =?us-ascii?Q?VBI/sG4fWGIB6QiHNzwSCbHvmfGK25kpizcNqHJJGOAMlcBBU0t8rwZrSpyd?= =?us-ascii?Q?ksUhy3OQS9IF7BNv1ipfMsHQR5DUD/ja87AtV/emjzlQyo/gqhAKMSh9yCjI?= =?us-ascii?Q?qa6XQcEGYoM1ObiyXf65icT5SShgHR00hFFtgS4B4ubBUQ5+Lc/Ylo3UdR9w?= =?us-ascii?Q?sXp9j5SSYIwSoScTAon/ix7Jud3WszvUxjA426+fmEmnhXKl0VGHBEbc/GET?= =?us-ascii?Q?9A0/Yf+RrEg3xh+IpR04hL/I?= X-OriginatorOrg: oracle.com X-MS-Exchange-CrossTenant-Network-Message-Id: 191fa47a-41ac-40e2-829b-08d8d4b56d4a X-MS-Exchange-CrossTenant-AuthSource: SJ0PR10MB4605.namprd10.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 Feb 2021 09:04:56.2326 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 4e2c6054-71cb-48f1-bd6c-3a9705aca71b X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: ZPfIezvB0z2y/VKag7vWE9jwCDQVFxACeK5niqxflr3yuqXKhOUYcEGI9TUWptwa9Vc2HbKe4kWX6bziVv6by8SpDpIWHRprRmnyTHZn3OM= X-MS-Exchange-Transport-CrossTenantHeadersStamped: BYAPR10MB3605 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=9899 signatures=668683 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 mlxlogscore=999 adultscore=0 mlxscore=0 bulkscore=0 suspectscore=0 malwarescore=0 spamscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2009150000 definitions=main-2102190070 X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=9899 signatures=668683 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 bulkscore=0 suspectscore=0 mlxscore=0 phishscore=0 spamscore=0 adultscore=0 clxscore=1015 impostorscore=0 priorityscore=1501 lowpriorityscore=0 malwarescore=0 mlxlogscore=999 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2009150000 definitions=main-2102190071 Content-Transfer-Encoding: 8bit Content-Type: text/plain Process fw_remove events in QemuCpuhpCollectApicIds() and collect corresponding APIC IDs for CPUs that are being hot-unplugged. In addition, we now ignore CPUs which only have remove set. These CPUs haven't been processed by OSPM yet. This is based on the QEMU hot-unplug protocol documented here: https://lore.kernel.org/qemu-devel/20201204170939.1815522-3-imammedo@redhat.com/ Cc: Laszlo Ersek Cc: Jordan Justen Cc: Ard Biesheuvel Cc: Igor Mammedov Cc: Boris Ostrovsky Cc: Aaron Young Ref: https://bugzilla.tianocore.org/show_bug.cgi?id=3132 Signed-off-by: Ankur Arora --- Notes: Addresses the following review comments from v6: (1,4) Move (and also rename) QEMU_CPUHP_STAT_EJECTED to patch 8, where we actually use it. (2) Downgrade debug mask from DEBUG_INFO to DEBUG_VERBOSE. (3a,3b,3c) Keep the CurrentSelector increment operation at the tail of the loop. () As discussed elsewhere we also need to get the CpuSelector while collecting ApicIds in QemuCpuhpCollectApicIds(). This patch adds a separate parameter for the CpuSelector values, because that works better alongside the hotplug ExtendIds logic. OvmfPkg/CpuHotplugSmm/QemuCpuhp.h | 1 + OvmfPkg/Include/IndustryStandard/QemuCpuHotplug.h | 1 + OvmfPkg/CpuHotplugSmm/CpuHotplug.c | 21 +++++- OvmfPkg/CpuHotplugSmm/QemuCpuhp.c | 84 ++++++++++++++++------- 4 files changed, 79 insertions(+), 28 deletions(-) diff --git a/OvmfPkg/CpuHotplugSmm/QemuCpuhp.h b/OvmfPkg/CpuHotplugSmm/QemuCpuhp.h index 8adaa0ad91f0..1e23b150910e 100644 --- a/OvmfPkg/CpuHotplugSmm/QemuCpuhp.h +++ b/OvmfPkg/CpuHotplugSmm/QemuCpuhp.h @@ -55,6 +55,7 @@ QemuCpuhpCollectApicIds ( OUT APIC_ID *PluggedApicIds, OUT UINT32 *PluggedCount, OUT APIC_ID *ToUnplugApicIds, + OUT UINT32 *ToUnplugSelector, OUT UINT32 *ToUnplugCount ); diff --git a/OvmfPkg/Include/IndustryStandard/QemuCpuHotplug.h b/OvmfPkg/Include/IndustryStandard/QemuCpuHotplug.h index a34a6d3fae61..2ec7a107a64d 100644 --- a/OvmfPkg/Include/IndustryStandard/QemuCpuHotplug.h +++ b/OvmfPkg/Include/IndustryStandard/QemuCpuHotplug.h @@ -34,6 +34,7 @@ #define QEMU_CPUHP_STAT_ENABLED BIT0 #define QEMU_CPUHP_STAT_INSERT BIT1 #define QEMU_CPUHP_STAT_REMOVE BIT2 +#define QEMU_CPUHP_STAT_FW_REMOVE BIT4 #define QEMU_CPUHP_RW_CMD_DATA 0x8 diff --git a/OvmfPkg/CpuHotplugSmm/CpuHotplug.c b/OvmfPkg/CpuHotplugSmm/CpuHotplug.c index bf68fcd42914..3192bfea1f15 100644 --- a/OvmfPkg/CpuHotplugSmm/CpuHotplug.c +++ b/OvmfPkg/CpuHotplugSmm/CpuHotplug.c @@ -52,6 +52,7 @@ STATIC CPU_HOT_PLUG_DATA *mCpuHotPlugData; // STATIC APIC_ID *mPluggedApicIds; STATIC APIC_ID *mToUnplugApicIds; +STATIC UINT32 *mToUnplugSelector; // // Address of the non-SMRAM reserved memory page that contains the Post-SMM Pen // for hot-added CPUs. @@ -289,6 +290,7 @@ CpuHotplugMmi ( mPluggedApicIds, &PluggedCount, mToUnplugApicIds, + mToUnplugSelector, &ToUnplugCount ); if (EFI_ERROR (Status)) { @@ -333,7 +335,9 @@ CpuHotplugEntry ( ) { EFI_STATUS Status; + UINTN Len; UINTN Size; + UINTN SizeSel; // // This module should only be included when SMM support is required. @@ -387,8 +391,9 @@ CpuHotplugEntry ( // // Allocate the data structures that depend on the possible CPU count. // - if (RETURN_ERROR (SafeUintnSub (mCpuHotPlugData->ArrayLength, 1, &Size)) || - RETURN_ERROR (SafeUintnMult (sizeof (APIC_ID), Size, &Size))) { + if (RETURN_ERROR (SafeUintnSub (mCpuHotPlugData->ArrayLength, 1, &Len)) || + RETURN_ERROR (SafeUintnMult (sizeof (APIC_ID), Len, &Size))|| + RETURN_ERROR (SafeUintnMult (sizeof (UINT32), Len, &SizeSel))) { Status = EFI_ABORTED; DEBUG ((DEBUG_ERROR, "%a: invalid CPU_HOT_PLUG_DATA\n", __FUNCTION__)); goto Fatal; @@ -405,6 +410,12 @@ CpuHotplugEntry ( DEBUG ((DEBUG_ERROR, "%a: MmAllocatePool(): %r\n", __FUNCTION__, Status)); goto ReleasePluggedApicIds; } + Status = gMmst->MmAllocatePool (EfiRuntimeServicesData, SizeSel, + (VOID **)&mToUnplugSelector); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "%a: MmAllocatePool(): %r\n", __FUNCTION__, Status)); + goto ReleaseToUnplugApicIds; + } // // Allocate the Post-SMM Pen for hot-added CPUs. @@ -412,7 +423,7 @@ CpuHotplugEntry ( Status = SmbaseAllocatePostSmmPen (&mPostSmmPenAddress, SystemTable->BootServices); if (EFI_ERROR (Status)) { - goto ReleaseToUnplugApicIds; + goto ReleaseToUnplugSelector; } // @@ -472,6 +483,10 @@ ReleasePostSmmPen: SmbaseReleasePostSmmPen (mPostSmmPenAddress, SystemTable->BootServices); mPostSmmPenAddress = 0; +ReleaseToUnplugSelector: + gMmst->MmFreePool (mToUnplugSelector); + mToUnplugSelector = NULL; + ReleaseToUnplugApicIds: gMmst->MmFreePool (mToUnplugApicIds); mToUnplugApicIds = NULL; diff --git a/OvmfPkg/CpuHotplugSmm/QemuCpuhp.c b/OvmfPkg/CpuHotplugSmm/QemuCpuhp.c index 8d4a6693c8d6..36372a5e6193 100644 --- a/OvmfPkg/CpuHotplugSmm/QemuCpuhp.c +++ b/OvmfPkg/CpuHotplugSmm/QemuCpuhp.c @@ -164,6 +164,9 @@ QemuCpuhpWriteCommand ( @param[out] ToUnplugApicIds The APIC IDs of the CPUs that are about to be hot-unplugged. + @param[out] ToUnplugSelector The QEMU Selectors of the CPUs that are about to + be hot-unplugged. + @param[out] ToUnplugCount The number of filled-in APIC IDs in ToUnplugApicIds. @@ -187,6 +190,7 @@ QemuCpuhpCollectApicIds ( OUT APIC_ID *PluggedApicIds, OUT UINT32 *PluggedCount, OUT APIC_ID *ToUnplugApicIds, + OUT UINT32 *ToUnplugSelector, OUT UINT32 *ToUnplugCount ) { @@ -204,6 +208,7 @@ QemuCpuhpCollectApicIds ( UINT32 PendingSelector; UINT8 CpuStatus; APIC_ID *ExtendIds; + UINT32 *ExtendSel; UINT32 *ExtendCount; APIC_ID NewApicId; @@ -245,10 +250,10 @@ QemuCpuhpCollectApicIds ( if ((CpuStatus & QEMU_CPUHP_STAT_INSERT) != 0) { // // The "insert" event guarantees the "enabled" status; plus it excludes - // the "remove" event. + // the "fw_remove" event. // if ((CpuStatus & QEMU_CPUHP_STAT_ENABLED) == 0 || - (CpuStatus & QEMU_CPUHP_STAT_REMOVE) != 0) { + (CpuStatus & QEMU_CPUHP_STAT_FW_REMOVE) != 0) { DEBUG ((DEBUG_ERROR, "%a: CurrentSelector=%u CpuStatus=0x%x: " "inconsistent CPU status\n", __FUNCTION__, CurrentSelector, CpuStatus)); @@ -259,40 +264,69 @@ QemuCpuhpCollectApicIds ( CurrentSelector)); ExtendIds = PluggedApicIds; + ExtendSel = NULL; ExtendCount = PluggedCount; - } else if ((CpuStatus & QEMU_CPUHP_STAT_REMOVE) != 0) { - DEBUG ((DEBUG_VERBOSE, "%a: CurrentSelector=%u: remove\n", __FUNCTION__, - CurrentSelector)); + } else if ((CpuStatus & QEMU_CPUHP_STAT_FW_REMOVE) != 0) { + // + // "fw_remove" event guarantees "enabled". + // + if ((CpuStatus & QEMU_CPUHP_STAT_ENABLED) == 0) { + DEBUG ((DEBUG_ERROR, "%a: CurrentSelector=%u CpuStatus=0x%x: " + "inconsistent CPU status\n", __FUNCTION__, CurrentSelector, + CpuStatus)); + return EFI_PROTOCOL_ERROR; + } + + DEBUG ((DEBUG_VERBOSE, "%a: CurrentSelector=%u: fw_remove\n", + __FUNCTION__, CurrentSelector)); ExtendIds = ToUnplugApicIds; + ExtendSel = ToUnplugSelector; ExtendCount = ToUnplugCount; + } else if ((CpuStatus & QEMU_CPUHP_STAT_REMOVE) != 0) { + // + // Let the OSPM deal with the "remove" event. + // + DEBUG ((DEBUG_VERBOSE, "%a: CurrentSelector=%u: remove (ignored)\n", + __FUNCTION__, CurrentSelector)); + + ExtendIds = NULL; + ExtendSel = NULL; + ExtendCount = NULL; } else { DEBUG ((DEBUG_VERBOSE, "%a: CurrentSelector=%u: no event\n", __FUNCTION__, CurrentSelector)); break; } - // - // Save the APIC ID of the CPU with the pending event, to the corresponding - // APIC ID array. - // - if (*ExtendCount == ApicIdCount) { - DEBUG ((DEBUG_ERROR, "%a: APIC ID array too small\n", __FUNCTION__)); - return EFI_BUFFER_TOO_SMALL; - } - QemuCpuhpWriteCommand (MmCpuIo, QEMU_CPUHP_CMD_GET_ARCH_ID); - NewApicId = QemuCpuhpReadCommandData (MmCpuIo); - DEBUG ((DEBUG_VERBOSE, "%a: ApicId=" FMT_APIC_ID "\n", __FUNCTION__, - NewApicId)); - ExtendIds[(*ExtendCount)++] = NewApicId; + ASSERT ((ExtendIds == NULL) == (ExtendCount == NULL)); + if (ExtendIds != NULL) { + // + // Save the APIC ID of the CPU with the pending event, to the + // corresponding APIC ID array. + // For unplug events, also save the CurrentSelector. + // + if (*ExtendCount == ApicIdCount) { + DEBUG ((DEBUG_ERROR, "%a: APIC ID array too small\n", __FUNCTION__)); + return EFI_BUFFER_TOO_SMALL; + } + QemuCpuhpWriteCommand (MmCpuIo, QEMU_CPUHP_CMD_GET_ARCH_ID); + NewApicId = QemuCpuhpReadCommandData (MmCpuIo); + DEBUG ((DEBUG_VERBOSE, "%a: ApicId=" FMT_APIC_ID "\n", __FUNCTION__, + NewApicId)); + if (ExtendSel != NULL) { + ExtendSel[(*ExtendCount)] = CurrentSelector; + } + ExtendIds[(*ExtendCount)++] = NewApicId; - // - // We've processed the CPU with (known) pending events, but we must never - // clear events. Therefore we need to advance past this CPU manually; - // otherwise, QEMU_CPUHP_CMD_GET_PENDING would stick to the currently - // selected CPU. - // - CurrentSelector++; + // + // We've processed the CPU with (known) pending events, but we must never + // clear events. Therefore we need to advance past this CPU manually; + // otherwise, QEMU_CPUHP_CMD_GET_PENDING would stick to the currently + // selected CPU. + // + CurrentSelector++; + } } while (CurrentSelector < PossibleCpuCount); DEBUG ((DEBUG_VERBOSE, "%a: PluggedCount=%u ToUnplugCount=%u\n", -- 2.9.3