From patchwork Wed Nov 6 00:39:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 13863787 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5EAA2D40D14 for ; Wed, 6 Nov 2024 00:40:12 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.830526.1245543 (Exim 4.92) (envelope-from ) id 1t8U5P-0007U3-1F; Wed, 06 Nov 2024 00:39:51 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 830526.1245543; Wed, 06 Nov 2024 00:39:51 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1t8U5O-0007Tw-Te; Wed, 06 Nov 2024 00:39:50 +0000 Received: by outflank-mailman (input) for mailman id 830526; Wed, 06 Nov 2024 00:39:48 +0000 Received: from se1-gles-sth1-in.inumbo.com ([159.253.27.254] helo=se1-gles-sth1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1t8U5M-0007S3-Oy for xen-devel@lists.xenproject.org; Wed, 06 Nov 2024 00:39:48 +0000 Received: from mail-ej1-x62b.google.com (mail-ej1-x62b.google.com [2a00:1450:4864:20::62b]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id 9d64042f-9bd7-11ef-a0c6-8be0dac302b0; Wed, 06 Nov 2024 01:39:43 +0100 (CET) Received: by mail-ej1-x62b.google.com with SMTP id a640c23a62f3a-a99f646ff1bso843693266b.2 for ; Tue, 05 Nov 2024 16:39:43 -0800 (PST) Received: from andrewcoop.eng.citrite.net ([185.25.67.249]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a9eb16d66b9sm198664166b.59.2024.11.05.16.39.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Nov 2024 16:39:41 -0800 (PST) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 9d64042f-9bd7-11ef-a0c6-8be0dac302b0 X-Custom-Connection: eyJyZW1vdGVpcCI6IjJhMDA6MTQ1MDo0ODY0OjIwOjo2MmIiLCJoZWxvIjoibWFpbC1lajEteDYyYi5nb29nbGUuY29tIn0= X-Custom-Transaction: eyJpZCI6IjlkNjQwNDJmLTliZDctMTFlZi1hMGM2LThiZTBkYWMzMDJiMCIsInRzIjoxNzMwODUzNTgzLjQ5MDEzMSwic2VuZGVyIjoiYW5kcmV3LmNvb3BlckBjbG91ZC5jb20iLCJyZWNpcGllbnQiOiJ4ZW4tZGV2ZWxAbGlzdHMueGVucHJvamVjdC5vcmcifQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1730853582; x=1731458382; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=qg2p2KdWuxuaSDUiJ7yQpVbcR99qOY01rSKquEZmgVI=; b=MHtQ36V5LBRxPc7FSpuz2QLzccbg7s60P4b4Pl/0wRuDEdsqRs80bg5fw3ccd7fV0t AcKugUcZ9Xxb4uMmRUGQjrGMcLp/wgBVecptFBpqtwDyfcrRKrJuduwZUW9Lcq5uUHwG InyoL5bycQTcbhlNhnKiNlCab9ze2o6/PA9oE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730853582; x=1731458382; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=qg2p2KdWuxuaSDUiJ7yQpVbcR99qOY01rSKquEZmgVI=; b=Ea90mtW1PO0+AMJ5cv+lctljTaBH4IOJ3F81nMMC44H01KZtnpurqZkV4SZiubjAH9 AVINIscHhHFQg3RAJGOWbzDfT+bfhbXpAgD9Awc55b0Pr8laf/VRa2ZYvzkoXiszQrsd T2JS939Ct8YigmBmzsSK8kxXl5m703G1Kp+/FYs9VDIeNh/Oqb8nhqvnCoEgq2yZ96EV KrmUspPOKM6jqbm3Djj4IQ/yGG5/sPHmzJoFzsMTIVOILUeQI0fj13rHxWTpw0MJQ4Px 44QZVPH4XXxlh0d+QNa3wntX3npv4rTY8ErdKjYlmyBhHGYYECiRzr89ULPMOZxRHVld sVdQ== X-Gm-Message-State: AOJu0Yw9WOYWSkJFdsilFu4pwV83tMMYzH5HSE+QT4+USzg7DlBtRYOt UJQyStl17mjxDnRLkwi2KhpONRf5Lz5tc6PyhQ6ujd7Rg/rUcwIxeNu0n7He5CcPOa6hsnSWZSC 2 X-Google-Smtp-Source: AGHT+IHG8CAkxzc9uWotSu9/8aMwFwGXV78MGz0LANQehu5h+v2rf2xbbw88T0N8fLiqFo1bR1l7Cw== X-Received: by 2002:a17:907:3202:b0:a9a:1a6a:b5f5 with SMTP id a640c23a62f3a-a9e3a7f0abamr2652933066b.56.1730853582157; Tue, 05 Nov 2024 16:39:42 -0800 (PST) From: Andrew Cooper To: Xen-devel Cc: Andrew Cooper , "Daniel P . Smith" , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Subject: [PATCH v2 1/4] x86/ucode: Enforce invariant about module selection Date: Wed, 6 Nov 2024 00:39:35 +0000 Message-Id: <20241106003938.3453243-2-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20241106003938.3453243-1-andrew.cooper3@citrix.com> References: <20241106003938.3453243-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 The work to add the `ucode=nmi` cmdline option left a subtle corner case. Both scan and an explicit index could be chosen, and we could really find both a CPIO archive and a microcode file. Worse, because the if/else chains for processing ucode_{blob,mod} are opposite ways around in early_microcode_load() and microcode_init_cache(), we can genuinely perform early microcode loading from the CPIO archive, then cache from the explicit file. Therefore, enforce that only one selection method can be active. Rename ucode_{scan,mod_idx} to have an opt_ prefix. This is both for consistency with the rest of Xen, and to guarantee that we've got all instances of the variables covered in this change. Explain how they're use. During cmdline/config parsing, always update both variables in pairs. In early_microcode_load(), ASSERT() the invariant just in case. Use a local variable for idx rather than operating on the static; we're the only consume of the value. Expand the index selection logic with comments and warnings to the user when something went wrong. Fixes: 5ed12565aa32 ("microcode: rendezvous CPUs in NMI handler and load ucode") Signed-off-by: Andrew Cooper Reviewed-by: Daniel P. Smith Reviewed-by: Jan Beulich --- CC: Jan Beulich CC: Roger Pau Monné CC: Daniel P. Smith This intentionally does not change the behaviour beyond excluding the unintended ambiguous case. It is deeply unintuitive behaviour, and there are complains on various distros forums/wikis. It ought to be changed, but not before we have a more sane way of handling modules. v2: * Adjust ucode=$num error case. Despite the fixes tag, this can't be backported (at least not in this form). --- xen/arch/x86/cpu/microcode/core.c | 80 +++++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 19 deletions(-) diff --git a/xen/arch/x86/cpu/microcode/core.c b/xen/arch/x86/cpu/microcode/core.c index b7c3e270e17e..97ed1f11588a 100644 --- a/xen/arch/x86/cpu/microcode/core.c +++ b/xen/arch/x86/cpu/microcode/core.c @@ -60,7 +60,6 @@ #define MICROCODE_UPDATE_TIMEOUT_US 1000000 static module_t __initdata ucode_mod; -static signed int __initdata ucode_mod_idx; static bool __initdata ucode_mod_forced; static unsigned int nr_cores; @@ -97,11 +96,6 @@ struct patch_with_flags { }; static struct ucode_mod_blob __initdata ucode_blob; -/* - * By default we will NOT parse the multiboot modules to see if there is - * cpio image with the microcode images. - */ -static bool __initdata ucode_scan; /* By default, ucode loading is done in NMI handler */ static bool ucode_in_nmi = true; @@ -109,13 +103,28 @@ static bool ucode_in_nmi = true; /* Protected by microcode_mutex */ static const struct microcode_patch *microcode_cache; +/* + * opt_mod_idx and opt_scan have subtle semantics. + * + * The cmdline can either identify a module by number (inc -ve back-reference) + * containing a raw microcode container, or select scan which instructs Xen to + * search all modules for an uncompressed CPIO archive containing a file with + * a vendor-dependent name. + * + * These options do not make sense when combined, so for the benefit of module + * location we require that they are not both active together. + */ +static int __initdata opt_mod_idx; +static bool __initdata opt_scan; + /* * Used by the EFI path only, when xen.cfg identifies an explicit microcode * file. Overrides ucode=|scan on the regular command line. */ void __init microcode_set_module(unsigned int idx) { - ucode_mod_idx = idx; + opt_mod_idx = idx; + opt_scan = false; ucode_mod_forced = 1; } @@ -139,14 +148,22 @@ static int __init cf_check parse_ucode(const char *s) else if ( !ucode_mod_forced ) /* Not forced by EFI */ { if ( (val = parse_boolean("scan", s, ss)) >= 0 ) - ucode_scan = val; + { + opt_scan = val; + opt_mod_idx = 0; + } else { const char *q; - ucode_mod_idx = simple_strtol(s, &q, 0); + opt_mod_idx = simple_strtol(s, &q, 0); if ( q != ss ) + { + opt_mod_idx = 0; rc = -EINVAL; + } + else + opt_scan = false; } } @@ -167,7 +184,7 @@ static void __init microcode_scan_module(struct boot_info *bi) int i; ucode_blob.size = 0; - if ( !ucode_scan ) + if ( !opt_scan ) return; /* @@ -806,7 +823,7 @@ static int __init cf_check microcode_init_cache(void) if ( !ucode_ops.apply_microcode ) return -ENODEV; - if ( ucode_scan ) + if ( opt_scan ) /* Need to rescan the modules because they might have been relocated */ microcode_scan_module(bi); @@ -831,17 +848,42 @@ static int __init early_microcode_load(struct boot_info *bi) const void *data = NULL; size_t size; struct microcode_patch *patch; + int idx = opt_mod_idx; + + /* + * Cmdline parsing ensures this invariant holds, so that we don't end up + * trying to mix multiple ways of finding the microcode. + */ + ASSERT(idx == 0 || !opt_scan); - if ( ucode_mod_idx < 0 ) - ucode_mod_idx += bi->nr_modules; - if ( ucode_mod_idx <= 0 || ucode_mod_idx >= bi->nr_modules || - !__test_and_clear_bit(ucode_mod_idx, bi->module_map) ) - goto scan; - ucode_mod = *bi->mods[ucode_mod_idx].mod; - scan: - if ( ucode_scan ) + if ( opt_scan ) /* Scan for a CPIO archive */ microcode_scan_module(bi); + if ( idx ) /* Specific module nominated */ + { + /* + * Negative indicies can be used to reference from the end of the + * modules. e.g. ucode=-1 refers to the last module. + */ + if ( idx < 0 ) + idx += bi->nr_modules; + + if ( idx <= 0 || idx >= bi->nr_modules ) + { + printk(XENLOG_WARNING "Microcode: Chosen module %d out of range [1, %u)\n", + idx, bi->nr_modules); + return -ENODEV; + } + + if ( !__test_and_clear_bit(idx, bi->module_map) ) + { + printk(XENLOG_WARNING "Microcode: Chosen module %d already used\n", idx); + return -ENODEV; + } + + ucode_mod = *bi->mods[idx].mod; + } + if ( !ucode_mod.mod_end && !ucode_blob.size ) return 0; From patchwork Wed Nov 6 00:39:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 13863786 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 49B3CD40D13 for ; Wed, 6 Nov 2024 00:40:12 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.830528.1245553 (Exim 4.92) (envelope-from ) id 1t8U5P-0007bh-Gi; Wed, 06 Nov 2024 00:39:51 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 830528.1245553; Wed, 06 Nov 2024 00:39:51 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1t8U5P-0007aQ-Bj; Wed, 06 Nov 2024 00:39:51 +0000 Received: by outflank-mailman (input) for mailman id 830528; Wed, 06 Nov 2024 00:39:49 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1t8U5N-0007Sp-HU for xen-devel@lists.xenproject.org; Wed, 06 Nov 2024 00:39:49 +0000 Received: from mail-ed1-x533.google.com (mail-ed1-x533.google.com [2a00:1450:4864:20::533]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 9e5a7052-9bd7-11ef-99a3-01e77a169b0f; Wed, 06 Nov 2024 01:39:45 +0100 (CET) Received: by mail-ed1-x533.google.com with SMTP id 4fb4d7f45d1cf-5ceca7df7f0so4365063a12.1 for ; Tue, 05 Nov 2024 16:39:45 -0800 (PST) Received: from andrewcoop.eng.citrite.net ([185.25.67.249]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a9eb16d66b9sm198664166b.59.2024.11.05.16.39.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Nov 2024 16:39:42 -0800 (PST) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 9e5a7052-9bd7-11ef-99a3-01e77a169b0f X-Custom-Connection: eyJyZW1vdGVpcCI6IjJhMDA6MTQ1MDo0ODY0OjIwOjo1MzMiLCJoZWxvIjoibWFpbC1lZDEteDUzMy5nb29nbGUuY29tIn0= X-Custom-Transaction: eyJpZCI6IjllNWE3MDUyLTliZDctMTFlZi05OWEzLTAxZTc3YTE2OWIwZiIsInRzIjoxNzMwODUzNTg1LjA2MzE0Nywic2VuZGVyIjoiYW5kcmV3LmNvb3BlckBjbG91ZC5jb20iLCJyZWNpcGllbnQiOiJ4ZW4tZGV2ZWxAbGlzdHMueGVucHJvamVjdC5vcmcifQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1730853584; x=1731458384; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Z05R7l9VYc7ghmXmXZQCFu9nX1F+8KLNBANLsMWOZCI=; b=KffKs29uychKMbgg7ifA/VKIrhEwz7ZX0VffCM7WyOPZAP/VuKw6RjDX5GGufNWIbC K/tbYfLs9AVTkBakwjWiat6Z2XNOSvAHnsKO+D5CPJw6tkUFoQohNkXhJ1OE6klgfeRh tXvKZHKkMqc2OwejonhKqFy88f8krMiNtPNPs= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730853584; x=1731458384; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Z05R7l9VYc7ghmXmXZQCFu9nX1F+8KLNBANLsMWOZCI=; b=lYrI1ZYR1MMTh37AVHrtRf8EMmR6tBNfRSeWNjd64pTrXHeiOKLkaRWc5glH+eTjGt cEmP3HU6hBgwYapFLTjsTdo8Q84V7ImhWXPaPYFIjLE1pUtwLbcx2y6gHC91vWlC+wLz WXGs3dRwmUPmkl0U986VqpFagK81rlQYdigwvMojRagHUlC+S2wyIKd+6RYV9+KQqsKM 6AjYtGFAwumA6Nbd7mVIhgYrY19bh6m22luHOnx+qfE+9PfAT6/L/WOJlS0S/UHwzTar 6FHc0gFn+OCeBbyfi4a3KDY2FLYjbdIcdl+JXrbljAU7mdx8mZYYHp45mtpQide7ZWUL +zyw== X-Gm-Message-State: AOJu0YwHRLTdwHkhxgyA0EA1h7ZxEVSnZojDyecKtxEFsiT4c3/8ezPo XCNETNfpIcQvuPxhDAhWJT3kFBULH4+WV6xaW/BAEfQBvYqpNvKPdwhf3VWaOJus+VtRKF7qro5 u X-Google-Smtp-Source: AGHT+IELiNk3d6+2EJT1O40P42H11PctsxY7oR3mNu8I1PiWpljSzKyQ7AGvIYC1PSQ2nfqyg69CTA== X-Received: by 2002:a17:907:2d10:b0:a9a:1115:486e with SMTP id a640c23a62f3a-a9e655b9327mr1752185166b.45.1730853583709; Tue, 05 Nov 2024 16:39:43 -0800 (PST) From: Andrew Cooper To: Xen-devel Cc: Andrew Cooper , Jan Beulich , "Daniel P . Smith" , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Subject: [PATCH v2 2/4] x86/ucode: Use bootstrap_unmap() in early_microcode_load() Date: Wed, 6 Nov 2024 00:39:36 +0000 Message-Id: <20241106003938.3453243-3-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20241106003938.3453243-1-andrew.cooper3@citrix.com> References: <20241106003938.3453243-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 If bootstrap_map() has provided a mapping, we must free it when done. Failing to do so may cause a spurious failure for unrelated logic later. Inserting a bootstrap_unmap() here does not break the use of ucode_{blob,mod} any more than they already are. Add a printk noting when we didn't find a microcode patch. It's at debug level, because this is the expected case on AMD Client systems, and SDPs, but for people trying to figure out why microcode loading isn't work, it might be helpful. Signed-off-by: Andrew Cooper Acked-by: Jan Beulich Reviewed-by: Daniel P. Smith --- CC: Jan Beulich CC: Roger Pau Monné CC: Daniel P. Smith v2: * Drop initialisation for rc. --- xen/arch/x86/cpu/microcode/core.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/xen/arch/x86/cpu/microcode/core.c b/xen/arch/x86/cpu/microcode/core.c index 97ed1f11588a..a2b03c52e86a 100644 --- a/xen/arch/x86/cpu/microcode/core.c +++ b/xen/arch/x86/cpu/microcode/core.c @@ -849,6 +849,7 @@ static int __init early_microcode_load(struct boot_info *bi) size_t size; struct microcode_patch *patch; int idx = opt_mod_idx; + int rc; /* * Cmdline parsing ensures this invariant holds, so that we don't end up @@ -904,15 +905,24 @@ static int __init early_microcode_load(struct boot_info *bi) patch = ucode_ops.cpu_request_microcode(data, size, false); if ( IS_ERR(patch) ) { - printk(XENLOG_WARNING "Parsing microcode blob error %ld\n", - PTR_ERR(patch)); - return PTR_ERR(patch); + rc = PTR_ERR(patch); + printk(XENLOG_WARNING "Microcode: Parse error %d\n", rc); + goto unmap; } if ( !patch ) - return -ENOENT; + { + printk(XENLOG_DEBUG "Microcode: No suitable patch found\n"); + rc = -ENOENT; + goto unmap; + } + + rc = microcode_update_cpu(patch, 0); - return microcode_update_cpu(patch, 0); + unmap: + bootstrap_unmap(); + + return rc; } int __init early_microcode_init(struct boot_info *bi) From patchwork Wed Nov 6 00:39:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 13863784 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1C8DCD40D13 for ; Wed, 6 Nov 2024 00:40:08 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.830530.1245581 (Exim 4.92) (envelope-from ) id 1t8U5R-0008Mk-7R; Wed, 06 Nov 2024 00:39:53 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 830530.1245581; Wed, 06 Nov 2024 00:39:53 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1t8U5R-0008MB-4Z; Wed, 06 Nov 2024 00:39:53 +0000 Received: by outflank-mailman (input) for mailman id 830530; Wed, 06 Nov 2024 00:39:51 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1t8U5P-0007Sp-Hs for xen-devel@lists.xenproject.org; Wed, 06 Nov 2024 00:39:51 +0000 Received: from mail-lf1-x12a.google.com (mail-lf1-x12a.google.com [2a00:1450:4864:20::12a]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 9f75ffdf-9bd7-11ef-99a3-01e77a169b0f; Wed, 06 Nov 2024 01:39:46 +0100 (CET) Received: by mail-lf1-x12a.google.com with SMTP id 2adb3069b0e04-539fb49c64aso8556873e87.0 for ; Tue, 05 Nov 2024 16:39:46 -0800 (PST) Received: from andrewcoop.eng.citrite.net ([185.25.67.249]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a9eb16d66b9sm198664166b.59.2024.11.05.16.39.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Nov 2024 16:39:43 -0800 (PST) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 9f75ffdf-9bd7-11ef-99a3-01e77a169b0f X-Custom-Connection: eyJyZW1vdGVpcCI6IjJhMDA6MTQ1MDo0ODY0OjIwOjoxMmEiLCJoZWxvIjoibWFpbC1sZjEteDEyYS5nb29nbGUuY29tIn0= X-Custom-Transaction: eyJpZCI6IjlmNzVmZmRmLTliZDctMTFlZi05OWEzLTAxZTc3YTE2OWIwZiIsInRzIjoxNzMwODUzNTg2Ljg3MzAzNywic2VuZGVyIjoiYW5kcmV3LmNvb3BlckBjbG91ZC5jb20iLCJyZWNpcGllbnQiOiJ4ZW4tZGV2ZWxAbGlzdHMueGVucHJvamVjdC5vcmcifQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1730853585; x=1731458385; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=zyQgfKHqhnuRdlQlcXH14Fl/zjVPFh80mAHLBVNbFoE=; b=W7rdOxpRRvNDCCxPPPWSSkc+98NwwSA8Hk4Uq1Fjy7EeptD7U3B8fjwJBS0xskkr8Z tc/h1hoikENk+3DJ8OR5KwSf8I+u6IAXRTCKl7iXgtImVQYAHYmP5W8toLAP5e2eTjG1 EUx2I0zOGUmVyrdKarlGyM7ebHJyE4KVKqDuQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730853585; x=1731458385; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zyQgfKHqhnuRdlQlcXH14Fl/zjVPFh80mAHLBVNbFoE=; b=Y8CkVtRrrvfdRAd0MErnJAabLBv5WVVzIG4satQ+c/Zmhrmf/L0Dd33fnFp/25TUnM aEaHFTPZ0baQFqtfSBwhzv8Nz9VnSQiktwnyoKl0gzWGlSMKJ1ECtbyt9MLXm0H+hHI8 +sylPtl9yWiYcawy5DbyavvZmlqw3aN8JEDZ0lD1aaXzK1IgubI34VtFmjJV5Tyb2lzc 3OsmDMFvd4ms8/yfCXGtuLZQWxi+XIQBymUsXTQBlgGya9LuC6YKTyB1KGM6MjJPmOGI DGqGZUKDBnN6m/tzsPzGkHAU27qG9JN2y9/wra3gpWO9yZ9ZDQjjNnUijeQsNlucfgPU vKgg== X-Gm-Message-State: AOJu0YzK8TSgFNNhE75CZhJuwsqakHYNbv6g+dKGK2v0ig8EbDHJ+nBC QuT0JUNJrom/dQiby6ZT8vjd2P1mTchaeN9GRh136JATSAaisfOEuw0PXvbNmeqGotsu+Cj8Hjl N X-Google-Smtp-Source: AGHT+IFAZmdgCeIMlHYBymCGBplHOzq9/OfOVuXyHDj3nTWLCsZO4+Y9UYY974om2FQDApwkbRwIsA== X-Received: by 2002:a05:6512:b94:b0:53b:1e70:6ab4 with SMTP id 2adb3069b0e04-53d65de3260mr14384511e87.14.1730853585415; Tue, 05 Nov 2024 16:39:45 -0800 (PST) From: Andrew Cooper To: Xen-devel Cc: Andrew Cooper , "Daniel P . Smith" , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Subject: [PATCH v2 3/4] x86/ucode: Drop ucode_mod and ucode_blob Date: Wed, 6 Nov 2024 00:39:37 +0000 Message-Id: <20241106003938.3453243-4-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20241106003938.3453243-1-andrew.cooper3@citrix.com> References: <20241106003938.3453243-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 Both are used to pass information from early_microcode_load() to microcode_init_cache(), and both constitute use-after-free's in certain cases. Later still in microcode_init() is a failed attempt to "free" this information, long after the damage has been done. * ucode_mod is a copy of the module_t identified by `ucode=$n`. It is a copy of the physical pointer from prior to Xen relocating the modules. microcode_init_cache() might happen to find the data still intact in it's old location, but it might be an arbitrary part of some other module. * ucode_blob is a stashed virtual pointer to a bootstrap_map() which becomes invalid the moment control returns to __start_xen(), where other logic is free to to make temporary mappings. This was even noticed and microcode_init_cache() adjusted to "fix" the stashed pointers. The information which should be passed between these two functions is which module to look in. Introduce early_mod_idx for this purpose. opt_scan can be reused to distinguish between CPIO archives and raw containers. Notably this means microcode_init_cache() doesn't need to scan all modules any more; we know exactly which one to look in. However, we do re-parse the CPIO header for simplicity. Furthermore, microcode_init_cache(), being a presmp_initcall does not need to use bootstrap_map() to access modules; it can use mfn_to_virt() directly, which avoids needing to funnel exit paths through bootstrap_unmap(). Fold microcode_scan_module() into what is now it's single caller. It operates on the function-wide idx/data/size state which allows for a unified "found" path irrespective of module selection method. Delete microcode_init() entirely. It was never legitimate logic. This resolves all issues to do with holding pointers (physical or virtual) across returning to __start_xen(). Signed-off-by: Andrew Cooper Reviewed-by: Daniel P. Smith --- CC: Jan Beulich CC: Roger Pau Monné CC: Daniel P. Smith v2: * Merge "x86/ucode: Delete the microcode_init() initcall" into this patch. --- xen/arch/x86/cpu/microcode/core.c | 194 ++++++++++++++---------------- 1 file changed, 89 insertions(+), 105 deletions(-) diff --git a/xen/arch/x86/cpu/microcode/core.c b/xen/arch/x86/cpu/microcode/core.c index a2b03c52e86a..74b816a98b17 100644 --- a/xen/arch/x86/cpu/microcode/core.c +++ b/xen/arch/x86/cpu/microcode/core.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -59,7 +58,6 @@ */ #define MICROCODE_UPDATE_TIMEOUT_US 1000000 -static module_t __initdata ucode_mod; static bool __initdata ucode_mod_forced; static unsigned int nr_cores; @@ -79,24 +77,11 @@ static enum { LOADING_EXIT, } loading_state; -/* - * If we scan the initramfs.cpio for the early microcode code - * and find it, then 'ucode_blob' will contain the pointer - * and the size of said blob. It is allocated from Xen's heap - * memory. - */ -struct ucode_mod_blob { - const void *data; - size_t size; -}; - struct patch_with_flags { unsigned int flags; const struct microcode_patch *patch; }; -static struct ucode_mod_blob __initdata ucode_blob; - /* By default, ucode loading is done in NMI handler */ static bool ucode_in_nmi = true; @@ -176,46 +161,6 @@ custom_param("ucode", parse_ucode); static struct microcode_ops __ro_after_init ucode_ops; -static void __init microcode_scan_module(struct boot_info *bi) -{ - uint64_t *_blob_start; - unsigned long _blob_size; - struct cpio_data cd; - int i; - - ucode_blob.size = 0; - if ( !opt_scan ) - return; - - /* - * Try all modules and see whichever could be the microcode blob. - */ - for ( i = 1 /* Ignore dom0 kernel */; i < bi->nr_modules; i++ ) - { - if ( !test_bit(i, bi->module_map) ) - continue; - - _blob_start = bootstrap_map(bi->mods[i].mod); - _blob_size = bi->mods[i].mod->mod_end; - if ( !_blob_start ) - { - printk("Could not map multiboot module #%d (size: %ld)\n", - i, _blob_size); - continue; - } - cd.data = NULL; - cd.size = 0; - cd = find_cpio_data(ucode_ops.cpio_path, _blob_start, _blob_size); - if ( cd.data ) - { - ucode_blob.size = cd.size; - ucode_blob.data = cd.data; - break; - } - bootstrap_unmap(); - } -} - static DEFINE_SPINLOCK(microcode_mutex); DEFINE_PER_CPU(struct cpu_signature, cpu_sig); @@ -754,28 +699,6 @@ int microcode_update(XEN_GUEST_HANDLE(const_void) buf, return continue_hypercall_on_cpu(0, microcode_update_helper, buffer); } -static int __init cf_check microcode_init(void) -{ - /* - * At this point, all CPUs should have updated their microcode - * via the early_microcode_* paths so free the microcode blob. - */ - if ( ucode_blob.size ) - { - bootstrap_unmap(); - ucode_blob.size = 0; - ucode_blob.data = NULL; - } - else if ( ucode_mod.mod_end ) - { - bootstrap_unmap(); - ucode_mod.mod_end = 0; - } - - return 0; -} -__initcall(microcode_init); - /* Load a cached update to current cpu */ int microcode_update_one(void) { @@ -815,23 +738,47 @@ static int __init early_update_cache(const void *data, size_t len) return rc; } +/* + * Set by early_microcode_load() to indicate where it found microcode, so + * microcode_init_cache() can find it again and initalise the cache. opt_scan + * tells us whether we're looking for a raw container or CPIO archive. + */ +static int __initdata early_mod_idx = -1; + static int __init cf_check microcode_init_cache(void) { struct boot_info *bi = &xen_boot_info; + void *data; + size_t size; int rc = 0; - if ( !ucode_ops.apply_microcode ) - return -ENODEV; + if ( early_mod_idx < 0 ) + /* early_microcode_load() didn't leave us any work to do. */ + return 0; + + size = bi->mods[early_mod_idx].mod->mod_end; + data = __mfn_to_virt(bi->mods[early_mod_idx].mod->mod_start); + /* + * If opt_scan is set, we're looking for a CPIO archive rather than a raw + * microcode container. Look within it. + */ if ( opt_scan ) - /* Need to rescan the modules because they might have been relocated */ - microcode_scan_module(bi); + { + struct cpio_data cd = find_cpio_data(ucode_ops.cpio_path, data, size); + + if ( !cd.data ) + { + printk(XENLOG_WARNING "Microcode: %s not found in CPIO archive\n", + strrchr(ucode_ops.cpio_path, '/') + 1); + return -ENOENT; + } + + data = cd.data; + size = cd.size; + } - if ( ucode_mod.mod_end ) - rc = early_update_cache(bootstrap_map(&ucode_mod), - ucode_mod.mod_end); - else if ( ucode_blob.size ) - rc = early_update_cache(ucode_blob.data, ucode_blob.size); + rc = early_update_cache(data, size); return rc; } @@ -845,7 +792,7 @@ presmp_initcall(microcode_init_cache); */ static int __init early_microcode_load(struct boot_info *bi) { - const void *data = NULL; + void *data = NULL; size_t size; struct microcode_patch *patch; int idx = opt_mod_idx; @@ -858,7 +805,40 @@ static int __init early_microcode_load(struct boot_info *bi) ASSERT(idx == 0 || !opt_scan); if ( opt_scan ) /* Scan for a CPIO archive */ - microcode_scan_module(bi); + { + for ( idx = 1; idx < bi->nr_modules; ++idx ) + { + struct cpio_data cd; + + if ( !test_bit(idx, bi->module_map) ) + continue; + + size = bi->mods[idx].mod->mod_end; + data = bootstrap_map_bm(&bi->mods[idx]); + if ( !data ) + { + printk(XENLOG_WARNING "Microcode: Could not map module %d, size %zu\n", + idx, size); + continue; + } + + cd = find_cpio_data(ucode_ops.cpio_path, data, size); + if ( !cd.data ) + { + /* CPIO archive, but no cpio_path. Try the next module */ + bootstrap_unmap(); + continue; + } + + data = cd.data; + size = cd.size; + goto found; + } + + printk(XENLOG_WARNING "Microcode: %s not found during CPIO scan\n", + strrchr(ucode_ops.cpio_path, '/') + 1); + return -ENODEV; + } if ( idx ) /* Specific module nominated */ { @@ -882,26 +862,21 @@ static int __init early_microcode_load(struct boot_info *bi) return -ENODEV; } - ucode_mod = *bi->mods[idx].mod; - } - - if ( !ucode_mod.mod_end && !ucode_blob.size ) - return 0; - - if ( ucode_blob.size ) - { - size = ucode_blob.size; - data = ucode_blob.data; - } - else if ( ucode_mod.mod_end ) - { - size = ucode_mod.mod_end; - data = bootstrap_map(&ucode_mod); + size = bi->mods[idx].mod->mod_end; + data = bootstrap_map_bm(&bi->mods[idx]); + if ( !data ) + { + printk(XENLOG_WARNING "Microcode: Could not map module %d, size %zu\n", + idx, size); + return -ENODEV; + } + goto found; } - if ( !data ) - return -ENOMEM; + /* No method of finding microcode specified. Nothing to do. */ + return 0; + found: patch = ucode_ops.cpu_request_microcode(data, size, false); if ( IS_ERR(patch) ) { @@ -917,6 +892,15 @@ static int __init early_microcode_load(struct boot_info *bi) goto unmap; } + /* + * We've found a microcode patch suitable for this CPU. + * + * Tell microcode_init_cache() which module we found it in. We cache it + * irrespective of whether the BSP successfully loads it; Some platforms + * are known to update the BSP but leave the APs on older ucode. + */ + early_mod_idx = idx; + rc = microcode_update_cpu(patch, 0); unmap: From patchwork Wed Nov 6 00:39:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 13863788 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 851E4D40D16 for ; Wed, 6 Nov 2024 00:40:13 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.830529.1245563 (Exim 4.92) (envelope-from ) id 1t8U5Q-0007pi-30; Wed, 06 Nov 2024 00:39:52 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 830529.1245563; Wed, 06 Nov 2024 00:39:52 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1t8U5P-0007oB-T2; Wed, 06 Nov 2024 00:39:51 +0000 Received: by outflank-mailman (input) for mailman id 830529; Wed, 06 Nov 2024 00:39:50 +0000 Received: from se1-gles-flk1-in.inumbo.com ([94.247.172.50] helo=se1-gles-flk1.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1t8U5O-0007Sp-JM for xen-devel@lists.xenproject.org; Wed, 06 Nov 2024 00:39:50 +0000 Received: from mail-ej1-x629.google.com (mail-ej1-x629.google.com [2a00:1450:4864:20::629]) by se1-gles-flk1.inumbo.com (Halon) with ESMTPS id 9fb9a4cc-9bd7-11ef-99a3-01e77a169b0f; Wed, 06 Nov 2024 01:39:47 +0100 (CET) Received: by mail-ej1-x629.google.com with SMTP id a640c23a62f3a-a9a4031f69fso968935466b.0 for ; Tue, 05 Nov 2024 16:39:47 -0800 (PST) Received: from andrewcoop.eng.citrite.net ([185.25.67.249]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-a9eb16d66b9sm198664166b.59.2024.11.05.16.39.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Nov 2024 16:39:45 -0800 (PST) X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" X-Inumbo-ID: 9fb9a4cc-9bd7-11ef-99a3-01e77a169b0f X-Custom-Connection: eyJyZW1vdGVpcCI6IjJhMDA6MTQ1MDo0ODY0OjIwOjo2MjkiLCJoZWxvIjoibWFpbC1lajEteDYyOS5nb29nbGUuY29tIn0= X-Custom-Transaction: eyJpZCI6IjlmYjlhNGNjLTliZDctMTFlZi05OWEzLTAxZTc3YTE2OWIwZiIsInRzIjoxNzMwODUzNTg3LjM2MzczMywic2VuZGVyIjoiYW5kcmV3LmNvb3BlckBjbG91ZC5jb20iLCJyZWNpcGllbnQiOiJ4ZW4tZGV2ZWxAbGlzdHMueGVucHJvamVjdC5vcmcifQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1730853586; x=1731458386; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=bivrP7RYzPcmWMZylrkIsrDnMjF+93O+ViHtEw4ZTZ4=; b=uZwA4D/MQOLYrOJiuxn4FDvBVmervwYd0xhVjtwhz9OM6r+id69xS4zMu/HeG+4ie4 eSQG92odQdWPSxBWSAd7Sa9VcNcN32cBxp9N5OLHKVWy9Iyc7SHg5cvVr4K7jGp/IbLB v6eH5y2qLcwf0pMtpCm50cBle3+uUD8Gi3xfY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1730853586; x=1731458386; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=bivrP7RYzPcmWMZylrkIsrDnMjF+93O+ViHtEw4ZTZ4=; b=BSDGN//Ilqu0jKJ0w6YMz7+ZJzmuTrSHrp+wnA1X9YcnZ65CokiiZO5BDd/bpOTjBa 9cSiQQkAJZTGfKZifdaWQhwRzjfszCI6uzmiMuwqqYJis2CIZAaoakLbDuAFmV6p1gzy i98Ory579lxXSYlwcrJgTxKVJ6u0QkQgNEIK6Hc/ewJkd2tnBvMcsPVtvVbFPuL/o3Ex evVYhaK1Vm1serGwMEzc5xR1YV1BBqYWlRvXG2n3qi6G+VPKWugCGEdKhRbjVoe6MCxH xdig7FmJ8jMbgjizSctbhWaBxmwEVeuA35aVYWlSKyYiEkXTxkS1kdZ7ketzP4JjzZHD OfWw== X-Gm-Message-State: AOJu0YzsHF+rUdOpJIbW8cN9m8/aK/GBkIRl2j2IENCs4u2Mr+JOiVLW LqapXrtQjuahvGtiGaQJfk4jYAB0tbEDHhU/FJP3NC2MBuA2dt95ilxe8CXmqfGiC5TnEljS0pz 4 X-Google-Smtp-Source: AGHT+IHOQD+MOwX+f3K42IcDvvL+zmdwP1SdeXuzPTIppUecycbvuCScfX3pkKpFSFFCKmBZi5/5Ug== X-Received: by 2002:a17:907:c8a0:b0:a9e:b287:2813 with SMTP id a640c23a62f3a-a9eb2875f42mr420633066b.5.1730853586157; Tue, 05 Nov 2024 16:39:46 -0800 (PST) From: Andrew Cooper To: Xen-devel Cc: Andrew Cooper , Jan Beulich , "Daniel P . Smith" , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Subject: [PATCH v2 4/4] x86/ucode: Fold early_update_cache() into its single caller Date: Wed, 6 Nov 2024 00:39:38 +0000 Message-Id: <20241106003938.3453243-5-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20241106003938.3453243-1-andrew.cooper3@citrix.com> References: <20241106003938.3453243-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 The data pointer is known good, so the -ENOMEM path is unnecessary. However, if we find no patch, something's wrong seeing as early_microcode_init() indicated it was happy. We are the entity initialising the cache, so we don't need the complexity of using microcode_update_cache(). Just assert the cache is empty, and populate it. Signed-off-by: Andrew Cooper Acked-by: Jan Beulich Reviewed-by: Daniel P. Smith --- CC: Jan Beulich CC: Roger Pau Monné CC: Daniel P. Smith --- xen/arch/x86/cpu/microcode/core.c | 47 +++++++++++++------------------ 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/xen/arch/x86/cpu/microcode/core.c b/xen/arch/x86/cpu/microcode/core.c index 74b816a98b17..54ce1b5e2ba6 100644 --- a/xen/arch/x86/cpu/microcode/core.c +++ b/xen/arch/x86/cpu/microcode/core.c @@ -711,33 +711,6 @@ int microcode_update_one(void) return microcode_update_cpu(NULL, 0); } -static int __init early_update_cache(const void *data, size_t len) -{ - int rc = 0; - struct microcode_patch *patch; - - if ( !data ) - return -ENOMEM; - - patch = parse_blob(data, len); - if ( IS_ERR(patch) ) - { - printk(XENLOG_WARNING "Parsing microcode blob error %ld\n", - PTR_ERR(patch)); - return PTR_ERR(patch); - } - - if ( !patch ) - return -ENOENT; - - spin_lock(µcode_mutex); - rc = microcode_update_cache(patch); - spin_unlock(µcode_mutex); - ASSERT(rc); - - return rc; -} - /* * Set by early_microcode_load() to indicate where it found microcode, so * microcode_init_cache() can find it again and initalise the cache. opt_scan @@ -748,6 +721,7 @@ static int __initdata early_mod_idx = -1; static int __init cf_check microcode_init_cache(void) { struct boot_info *bi = &xen_boot_info; + struct microcode_patch *patch; void *data; size_t size; int rc = 0; @@ -778,7 +752,24 @@ static int __init cf_check microcode_init_cache(void) size = cd.size; } - rc = early_update_cache(data, size); + patch = parse_blob(data, size); + if ( IS_ERR(patch) ) + { + rc = PTR_ERR(patch); + printk(XENLOG_WARNING "Microcode: Parse error %d\n", rc); + return rc; + } + + if ( !patch ) + { + printk(XENLOG_WARNING "Microcode: No suitable patch found\n"); + return -ENOENT; + } + + spin_lock(µcode_mutex); + ASSERT(microcode_cache == NULL); + microcode_cache = patch; + spin_unlock(µcode_mutex); return rc; }