From patchwork Thu Dec 8 13:26:38 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Dyasli X-Patchwork-Id: 13068398 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 191DBC4332F for ; Thu, 8 Dec 2022 13:27:00 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.457126.714971 (Exim 4.92) (envelope-from ) id 1p3GvK-0000XK-9H; Thu, 08 Dec 2022 13:26:50 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 457126.714971; Thu, 08 Dec 2022 13:26:50 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1p3GvK-0000XD-4b; Thu, 08 Dec 2022 13:26:50 +0000 Received: by outflank-mailman (input) for mailman id 457126; Thu, 08 Dec 2022 13:26:49 +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 1p3GvJ-0000X7-Dk for xen-devel@lists.xenproject.org; Thu, 08 Dec 2022 13:26:49 +0000 Received: from esa1.hc3370-68.iphmx.com (esa1.hc3370-68.iphmx.com [216.71.145.142]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id f5a6bbf2-76fb-11ed-91b6-6bf2151ebd3b; Thu, 08 Dec 2022 14:26:46 +0100 (CET) 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: f5a6bbf2-76fb-11ed-91b6-6bf2151ebd3b DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1670506007; h=from:to:cc:subject:date:message-id:mime-version; bh=ZPfarfZcEejGSJqVF4CTnChPnnzcwhgygBNP/5MhZXk=; b=UYEXhOl5b8/Jna+0iVYl60UPP6ZxImBwjDUGLfAvG7F4iuczwsDyjwWt tWOJK7uMJW4zmkDY8wf++KK5lNYVoEYWfo4b7t1TLiVtLp+D3MCqGsLqq tEB6CL+KpOpM8A2h3eFm+4T5y2SQfQHMLWfPbWYlgFDtpS9SXaREYJc2a w=; Authentication-Results: esa1.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none X-SBRS: 4.0 X-MesageID: 87664792 X-Ironport-Server: esa1.hc3370-68.iphmx.com X-Remote-IP: 162.221.156.83 X-Policy: $RELAYED IronPort-Data: A9a23:joPi/aAzYZ8/yhVW/yLjw5YqxClBgxIJ4kV8jS/XYbTApG8jg2MAm mIdUWCGOfiIYTGnfNEga9yz/EhXupHUn9ZiQQY4rX1jcSlH+JHPbTi7wuUcHAvJd5GeExg3h yk6QoOdRCzhZiaE/n9BCpC48T8nk/nNHuCnYAL9EngZbRd+Tys8gg5Ulec8g4p56fC0GArIs t7pyyHlEAbNNwVcbyRFtcpvlDs15K6o4WlA7gRnDRx2lAS2e0c9Xcp3yZ6ZdxMUcqEMdsamS uDKyq2O/2+x13/B3fv8z94X2mVTKlLjFVDmZkh+AsBOsTAbzsAG6Y4pNeJ0VKtio27hc+ada jl6ncfYpQ8BZsUgkQmGOvVSO3kW0aZuoNcrLZUj2CA6IoKvn3bEmp1T4E8K0YIw4sVcHjge3 PchAXNSdDeSt8+KxYmLVbw57igjBJGD0II3v3hhyXfSDOo8QICFSKLPjTNa9G5u3IYUR6+YP pdHL2o0BPjDS0Qn1lM/E58kk+q5wHXueiZcqXqepLYt4niVxwt0uFToGIqKJILWGpQP9qqej kDK1n/BLzoxDt2WzWag8zGRm7b+jDyuDer+E5Xnr6U30TV/3Fc7Fxk+RVa95/6jhSaWS99Zb kAZ5Ccqhawz71CwCMnwWQWip3yJtQJaXMBfe8U44gyQzqvf4y6CG3MJCDVGbbQbWNQeHGJwk AXTxpWwWGIp4Ob9pW+hGqm8tRCZJnFFBGQ7TGxbVywU0/TfpboDkUeaJjp8K5KdgtrwEDD25 jmFqikimrke5fI2O7WHEUPv2Gz1+MWQJuIhzkCOBz/+sFslDGKwT9bwgWU3+8qsO2pworOpm HEf0/aT4+kVZX1mvHzcGb5ddF1FChvsDdE9vbKNN8N5n9hO0yT5FWy13N2ZDBkBDyr8UWW1C HI/QCsIjHOpAFOkbLVsf6W6ANkwwK7rGLzND66LNoYVMsAqLVXZpEmCgHJ8OEi0wSARfVwXY 8/HIa5A815FYUiY8NZGb7hEiuJ6rszP7WjSWYr633yaPUm2PRaopUM+GALWNIgRtfrUyDg5B v4Db6NmPT0DCryhCsQWmKZPRW03wY8TXMyt95QNKLfcSuekcUl4Y8LsLXoaU9QNt8xoei3gp xlRhmcwJILDuED6 IronPort-HdrOrdr: A9a23:Jq2DjKy/i1XwqTZQno+fKrPw1r1zdoMgy1knxilNoHxuH/BwWf rPoB17726RtN91YhsdcL+7V5VoLUmzyXcX2/h1AV7BZniEhILAFugLgbcKqweKJ8SUzJ8+6U 4PSclD4N2bNykGsS75ijPIb+rJFrO8gd+VbeS19QYScelzAZsQiDuQkmygYzZLrA8tP+teKL OsovBpihCHYnotYsGyFhA+LpL+T42iruOeXfYebSRXkDWzsQ== X-IronPort-AV: E=Sophos;i="5.96,227,1665460800"; d="scan'208";a="87664792" From: Sergey Dyasli To: CC: Jan Beulich , Andrew Cooper , =?utf-8?q?Roger_Pau_Monn=C3=A9?= , Wei Liu , Sergey Dyasli Subject: [PATCH 1/2] x86/ucode: allow cpu_request_microcode() to skip memory allocation Date: Thu, 8 Dec 2022 13:26:38 +0000 Message-ID: <20221208132639.29942-1-sergey.dyasli@citrix.com> X-Mailer: git-send-email 2.17.1 MIME-Version: 1.0 This is a preparatory step in order to do earlier microcode loading on the boot CPU when the domain heap has not been initialized yet and xmalloc still unavailable. Add make_copy argument which will allow to load microcode directly from the blob bypassing microcode_cache. Add const qualifiers where required. Signed-off-by: Sergey Dyasli Signed-off-by: Jan Beulich --- xen/arch/x86/cpu/microcode/amd.c | 17 +++++++++++------ xen/arch/x86/cpu/microcode/core.c | 18 +++++++++--------- xen/arch/x86/cpu/microcode/intel.c | 17 +++++++++++------ xen/arch/x86/cpu/microcode/private.h | 18 ++++++++++++------ 4 files changed, 43 insertions(+), 27 deletions(-) diff --git a/xen/arch/x86/cpu/microcode/amd.c b/xen/arch/x86/cpu/microcode/amd.c index 8195707ee1..d4df3c4806 100644 --- a/xen/arch/x86/cpu/microcode/amd.c +++ b/xen/arch/x86/cpu/microcode/amd.c @@ -299,11 +299,11 @@ static int scan_equiv_cpu_table(const struct container_equiv_table *et) return -ESRCH; } -static struct microcode_patch *cf_check cpu_request_microcode( - const void *buf, size_t size) +static const struct microcode_patch *cf_check cpu_request_microcode( + const void *buf, size_t size, bool make_copy) { const struct microcode_patch *saved = NULL; - struct microcode_patch *patch = NULL; + const struct microcode_patch *patch = NULL; size_t saved_size = 0; int error = 0; @@ -411,9 +411,14 @@ static struct microcode_patch *cf_check cpu_request_microcode( if ( saved ) { - patch = xmemdup_bytes(saved, saved_size); - if ( !patch ) - error = -ENOMEM; + if ( make_copy ) + { + patch = xmemdup_bytes(saved, saved_size); + if ( !patch ) + error = -ENOMEM; + } + else + patch = saved; } if ( error && !patch ) diff --git a/xen/arch/x86/cpu/microcode/core.c b/xen/arch/x86/cpu/microcode/core.c index 452a7ca773..924a2bd7b5 100644 --- a/xen/arch/x86/cpu/microcode/core.c +++ b/xen/arch/x86/cpu/microcode/core.c @@ -99,7 +99,7 @@ static bool ucode_in_nmi = true; bool __read_mostly opt_ucode_allow_same; /* Protected by microcode_mutex */ -static struct microcode_patch *microcode_cache; +static const struct microcode_patch *microcode_cache; void __init microcode_set_module(unsigned int idx) { @@ -240,20 +240,20 @@ static const struct microcode_patch *nmi_patch = ZERO_BLOCK_PTR; * patch is found and an error occurs during the parsing process. Otherwise * return NULL. */ -static struct microcode_patch *parse_blob(const char *buf, size_t len) +static const struct microcode_patch *parse_blob(const char *buf, size_t len) { alternative_vcall(ucode_ops.collect_cpu_info); - return alternative_call(ucode_ops.cpu_request_microcode, buf, len); + return alternative_call(ucode_ops.cpu_request_microcode, buf, len, true); } -static void microcode_free_patch(struct microcode_patch *patch) +static void microcode_free_patch(const struct microcode_patch *patch) { - xfree(patch); + xfree((void *)patch); } /* Return true if cache gets updated. Otherwise, return false */ -static bool microcode_update_cache(struct microcode_patch *patch) +static bool microcode_update_cache(const struct microcode_patch *patch) { ASSERT(spin_is_locked(µcode_mutex)); @@ -565,7 +565,7 @@ static long cf_check microcode_update_helper(void *data) int ret; struct ucode_buf *buffer = data; unsigned int cpu, updated; - struct microcode_patch *patch; + const struct microcode_patch *patch; /* cpu_online_map must not change during update */ if ( !get_cpu_maps() ) @@ -648,7 +648,7 @@ static long cf_check microcode_update_helper(void *data) * this requirement can be relaxed in the future. Right now, this is * conservative and good. */ - ret = stop_machine_run(do_microcode_update, patch, NR_CPUS); + ret = stop_machine_run(do_microcode_update, (void *)patch, NR_CPUS); updated = atomic_read(&cpu_updated); if ( updated > 0 ) @@ -738,7 +738,7 @@ static int __init early_microcode_update_cpu(void) int rc = 0; const void *data = NULL; size_t len; - struct microcode_patch *patch; + const struct microcode_patch *patch; if ( ucode_blob.size ) { diff --git a/xen/arch/x86/cpu/microcode/intel.c b/xen/arch/x86/cpu/microcode/intel.c index f5ba6d76d7..017f37e43d 100644 --- a/xen/arch/x86/cpu/microcode/intel.c +++ b/xen/arch/x86/cpu/microcode/intel.c @@ -323,12 +323,12 @@ static int cf_check apply_microcode(const struct microcode_patch *patch) return 0; } -static struct microcode_patch *cf_check cpu_request_microcode( - const void *buf, size_t size) +static const struct microcode_patch *cf_check cpu_request_microcode( + const void *buf, size_t size, bool make_copy) { int error = 0; const struct microcode_patch *saved = NULL; - struct microcode_patch *patch = NULL; + const struct microcode_patch *patch = NULL; while ( size ) { @@ -364,10 +364,15 @@ static struct microcode_patch *cf_check cpu_request_microcode( if ( saved ) { - patch = xmemdup_bytes(saved, get_totalsize(saved)); + if ( make_copy ) + { + patch = xmemdup_bytes(saved, get_totalsize(saved)); - if ( !patch ) - error = -ENOMEM; + if ( !patch ) + error = -ENOMEM; + } + else + patch = saved; } if ( error && !patch ) diff --git a/xen/arch/x86/cpu/microcode/private.h b/xen/arch/x86/cpu/microcode/private.h index c085a10268..98657d39c3 100644 --- a/xen/arch/x86/cpu/microcode/private.h +++ b/xen/arch/x86/cpu/microcode/private.h @@ -23,16 +23,22 @@ struct microcode_ops { * older that what is running in the CPU. This is a feature, to better * cope with corner cases from buggy firmware.) * - * If one is found, allocate and return a struct microcode_patch - * encapsulating the appropriate microcode patch. Does not alias the - * original buffer. Must be suitable to be freed with a single xfree(). + * If one is found, behaviour depends on the make_copy argument: + * + * true: allocate and return a struct microcode_patch encapsulating + * the appropriate microcode patch. Does not alias the original + * buffer. Must be suitable to be freed with a single xfree(). + * + * false: return a pointer to the patch within the original buffer. + * This is useful for early microcode loading when xmalloc might + * not be available yet. * * If one is not found, (nothing matches the current CPU), return NULL. * Also may return ERR_PTR(-err), e.g. bad container, out of memory. */ - struct microcode_patch *(*cpu_request_microcode)(const void *buf, - size_t size); - + const struct microcode_patch *(*cpu_request_microcode)(const void *buf, + size_t size, + bool make_copy); /* * Obtain microcode-relevant details for the current CPU. Results in * per_cpu(cpu_sig). From patchwork Thu Dec 8 13:26:39 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Dyasli X-Patchwork-Id: 13068399 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 ECB7DC4332F for ; Thu, 8 Dec 2022 13:27:12 +0000 (UTC) Received: from list by lists.xenproject.org with outflank-mailman.457129.714982 (Exim 4.92) (envelope-from ) id 1p3GvU-0000rv-LV; Thu, 08 Dec 2022 13:27:00 +0000 X-Outflank-Mailman: Message body and most headers restored to incoming version Received: by outflank-mailman (output) from mailman id 457129.714982; Thu, 08 Dec 2022 13:27:00 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1p3GvU-0000rm-Hq; Thu, 08 Dec 2022 13:27:00 +0000 Received: by outflank-mailman (input) for mailman id 457129; Thu, 08 Dec 2022 13:26:59 +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 1p3GvS-0000X7-RE for xen-devel@lists.xenproject.org; Thu, 08 Dec 2022 13:26:58 +0000 Received: from esa6.hc3370-68.iphmx.com (esa6.hc3370-68.iphmx.com [216.71.155.175]) by se1-gles-sth1.inumbo.com (Halon) with ESMTPS id fbeb36c3-76fb-11ed-91b6-6bf2151ebd3b; Thu, 08 Dec 2022 14:26:57 +0100 (CET) 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: fbeb36c3-76fb-11ed-91b6-6bf2151ebd3b DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1670506017; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=mUQ9fo4KGms+nfgI98Sxyt/O96CD/Xb0KR7B0QCJECM=; b=INnqoHFDJ6pGoIuwgDhOo57H+q7OD4ytx4e+TixvP+yXTv/AeOT0BQ2x cvV0QGaz6TtgGTf/CduTYseo0l/3mKq40bTcjmkPTSveXifyvSodqiELI aij/FVZlYm1ZXTM32gbzqVtTG6MIqYQW/4uu4wa2uFpneqJRXijeRbkVj U=; Authentication-Results: esa6.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none X-SBRS: 4.0 X-MesageID: 86800782 X-Ironport-Server: esa6.hc3370-68.iphmx.com X-Remote-IP: 162.221.156.83 X-Policy: $RELAYED IronPort-Data: A9a23:3+KMYq4cZi/x00BVyapzgQxRtDPHchMFZxGqfqrLsTDasY5as4F+v mIeXGyFPvuPa2H0c9EgbN7j9k9VvJCAzIdgSQU/qCg2Hi5G8cbLO4+Ufxz6V8+wwm8vb2o8t plDNYOQRCwQZiWBzvt4GuG59RGQ7YnRGvynTraBYnoqLeNdYH9JoQp5nOIkiZJfj9G8Agec0 fv/uMSaM1K+s9JOGjt8B5mr9VU+4pwehBtC5gZkPKoT7AeH/5UoJMl3yZ+ZfiOQrrZ8RoZWd 86bpJml82XQ+QsaC9/Nut4XpWVTH9Y+lSDX4pZnc/DKbipq/0Te4Y5iXBYoUm9Fii3hojxE4 I4lWapc6+seFvakdOw1C3G0GszlVEFM0OevzXOX6aR/w6BaGpdFLjoH4EweZOUlFuhL7W5m3 O01dDwvagq5vt2ayvWeUvR1tN5/BZy+VG8fkikIITDxCP8nRdbIQrnQ5M8e1zA17ixMNa+AP YxDM2MpNUmeJU0UUrsUIMtWcOOAnXTlfDBJ7l6ErLEz4kDYzRBr0airO93QEjCPbZULzh7A+ TKcl4j/KhI8N9am7BGkyHWxrazhoXPaQ9kRLrLto5aGh3XMnzdOWXX6T2CTvv2RmkO4HdVFJ CQ86ico6KQ/6kGvZt38RAGj5m6JuAYGXNhdGPF87xuCooLW6QuEAmkPThZadccr8sQxQFQXO kShxo2zQ2Y16fvMFCzbpuz8QS6O1TY9BH4vOSMmSRE/2ubPqsYWlg/WfMw/Ofvg5jHqIg3Yz zePpSk4orwci88Xyqm2lWz6byKQSovhFVBsuFiONo6xxkYgPdP+OdT0gbTOxawYRLt1WGVtq 5TtdyK2yOkVRa+AmyWWKAnmNOH4vq3VWNEwbLMGInXAy9hP0yT7FWyzyGskTKuMDirjUWGBX aMrkVkNjKK/xVPzBUONX6q/Ct4x0Y/rHsn/W/bfY7JmO8YuLFPcrHk1PBTOhwgBdXTAdolma P+mnTuEVy5GWcyLMhLpLwvi7VPb7n9nnj6CLXwK5x+mzaCfdBaopUQtaTOzghQCxPrc+m39q o8PX/ZmPj0DCIUSlAGLq99MRb3LRFBnba3LRzt/L7LYflI8Rjh+YxITqJt4E7FYc21uvr+g1 hmAtoVwlDITWVWvxd22V01e IronPort-HdrOrdr: A9a23:CZI6hqAzYH/3FwblHelW55DYdb4zR+YMi2TDt3oddfWaSKylfq GV7ZAmPHrP4gr5N0tOpTntAse9qBDnhPtICOsqTNSftWDd0QPFEGgL1+DfKlbbak/DH4BmtJ uJc8JFeaDN5VoRt7eH3OFveexQv+Vu88qT9JnjJ28Gd3AMV0n5hT0JcTpyFCdNNW97LKt8Lr WwzOxdqQGtfHwGB/7LfEXsD4D41qT2fIuNW29/OyIa X-IronPort-AV: E=Sophos;i="5.96,227,1665460800"; d="scan'208";a="86800782" From: Sergey Dyasli To: CC: Jan Beulich , Andrew Cooper , =?utf-8?q?Roger_Pau_Monn=C3=A9?= , Wei Liu , Sergey Dyasli Subject: [PATCH 2/2] x86/ucode: load microcode earlier on boot CPU Date: Thu, 8 Dec 2022 13:26:39 +0000 Message-ID: <20221208132639.29942-2-sergey.dyasli@citrix.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20221208132639.29942-1-sergey.dyasli@citrix.com> References: <20221208132639.29942-1-sergey.dyasli@citrix.com> MIME-Version: 1.0 Call early_microcode_init() straight after multiboot modules become accessible. Modify it to load the ucode directly from the blob bypassing populating microcode_cache because xmalloc is still not available at that point during Xen boot. Introduce early_microcode_init_cache() for populating microcode_cache. It needs to find the new virtual address of the ucode blob because it changes during boot, e.g. from 0x00000000010802fc to 0xffff83204dac52fc. Signed-off-by: Sergey Dyasli --- xen/arch/x86/cpu/microcode/core.c | 61 ++++++++++++++++++++++++---- xen/arch/x86/include/asm/microcode.h | 6 ++- xen/arch/x86/include/asm/setup.h | 3 -- xen/arch/x86/setup.c | 10 +++-- 4 files changed, 64 insertions(+), 16 deletions(-) diff --git a/xen/arch/x86/cpu/microcode/core.c b/xen/arch/x86/cpu/microcode/core.c index 924a2bd7b5..b04b30ce5e 100644 --- a/xen/arch/x86/cpu/microcode/core.c +++ b/xen/arch/x86/cpu/microcode/core.c @@ -198,7 +198,7 @@ void __init microcode_scan_module( bootstrap_map(NULL); } } -void __init microcode_grab_module( +static void __init microcode_grab_module( unsigned long *module_map, const multiboot_info_t *mbi) { @@ -733,9 +733,35 @@ int microcode_update_one(void) } /* BSP calls this function to parse ucode blob and then apply an update. */ -static int __init early_microcode_update_cpu(void) +static int __init early_microcode_update_cache(const void *data, size_t len) { int rc = 0; + const 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; +} + +static int __init early_microcode_update_cpu(void) +{ const void *data = NULL; size_t len; const struct microcode_patch *patch; @@ -754,7 +780,9 @@ static int __init early_microcode_update_cpu(void) if ( !data ) return -ENOMEM; - patch = parse_blob(data, len); + alternative_vcall(ucode_ops.collect_cpu_info); + + patch = alternative_call(ucode_ops.cpu_request_microcode, data, len, false); if ( IS_ERR(patch) ) { printk(XENLOG_WARNING "Parsing microcode blob error %ld\n", @@ -765,15 +793,28 @@ static int __init early_microcode_update_cpu(void) if ( !patch ) return -ENOENT; - spin_lock(µcode_mutex); - rc = microcode_update_cache(patch); - spin_unlock(µcode_mutex); - ASSERT(rc); + return microcode_update_cpu(patch); +} + +int __init early_microcode_init_cache(unsigned long *module_map, + const multiboot_info_t *mbi) +{ + int rc = 0; + + /* Need to rescan the modules because they might have been relocated */ + microcode_grab_module(module_map, mbi); + + if ( ucode_mod.mod_end ) + rc = early_microcode_update_cache(bootstrap_map(&ucode_mod), + ucode_mod.mod_end); + else if ( ucode_blob.size ) + rc = early_microcode_update_cache(ucode_blob.data, ucode_blob.size); - return microcode_update_one(); + return rc; } -int __init early_microcode_init(void) +int __init early_microcode_init(unsigned long *module_map, + const multiboot_info_t *mbi) { const struct cpuinfo_x86 *c = &boot_cpu_data; int rc = 0; @@ -797,6 +838,8 @@ int __init early_microcode_init(void) return -ENODEV; } + microcode_grab_module(module_map, mbi); + alternative_vcall(ucode_ops.collect_cpu_info); if ( ucode_mod.mod_end || ucode_blob.size ) diff --git a/xen/arch/x86/include/asm/microcode.h b/xen/arch/x86/include/asm/microcode.h index 3b0234e9fa..c5f9897535 100644 --- a/xen/arch/x86/include/asm/microcode.h +++ b/xen/arch/x86/include/asm/microcode.h @@ -3,6 +3,7 @@ #include #include +#include #include @@ -21,7 +22,10 @@ DECLARE_PER_CPU(struct cpu_signature, cpu_sig); void microcode_set_module(unsigned int idx); int microcode_update(XEN_GUEST_HANDLE(const_void), unsigned long len); -int early_microcode_init(void); +int early_microcode_init(unsigned long *module_map, + const multiboot_info_t *mbi); +int early_microcode_init_cache(unsigned long *module_map, + const multiboot_info_t *mbi); int microcode_update_one(void); #endif /* ASM_X86__MICROCODE_H */ diff --git a/xen/arch/x86/include/asm/setup.h b/xen/arch/x86/include/asm/setup.h index 21037b7f31..82ee51c2dc 100644 --- a/xen/arch/x86/include/asm/setup.h +++ b/xen/arch/x86/include/asm/setup.h @@ -45,9 +45,6 @@ void *bootstrap_map(const module_t *mod); int xen_in_range(unsigned long mfn); -void microcode_grab_module( - unsigned long *, const multiboot_info_t *); - extern uint8_t kbd_shift_flags; #ifdef NDEBUG diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index e05189f649..9955e1e6fa 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -1178,6 +1178,12 @@ void __init noreturn __start_xen(unsigned long mbi_p) mod[i].reserved = 0; } + /* + * TODO: load ucode earlier once multiboot modules become accessible + * at an earlier stage. + */ + early_microcode_init(module_map, mbi); + if ( xen_phys_start ) { relocated = true; @@ -1774,11 +1780,9 @@ void __init noreturn __start_xen(unsigned long mbi_p) init_IRQ(); - microcode_grab_module(module_map, mbi); - timer_init(); - early_microcode_init(); + early_microcode_init_cache(module_map, mbi); tsx_init(); /* Needs microcode. May change HLE/RTM feature bits. */