From patchwork Tue Mar 31 10:05:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11467197 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 79D8A92C for ; Tue, 31 Mar 2020 10:06:39 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 562F820781 for ; Tue, 31 Mar 2020 10:06:39 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="asVgDJxb" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 562F820781 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jJDmE-0005mF-6h; Tue, 31 Mar 2020 10:05:46 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jJDmC-0005lP-8g for xen-devel@lists.xenproject.org; Tue, 31 Mar 2020 10:05:44 +0000 X-Inumbo-ID: 2b9d0b55-7337-11ea-ba0b-12813bfff9fa Received: from esa1.hc3370-68.iphmx.com (unknown [216.71.145.142]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 2b9d0b55-7337-11ea-ba0b-12813bfff9fa; Tue, 31 Mar 2020 10:05:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1585649139; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=fEEGaZOBZD3UVLJz2S52FnWKJLru30PNLNWhLEp6KAs=; b=asVgDJxbhoKuYtdj9ndvzTAtrtnjHt93sXJCOKHBsAhBHiq7iSmlk4G4 xF4WFBjZHsYKmRH9ZPUGsK/1vyP1lIf4JwnpdTK2RudRXJhXr8sxf9lLD b4+V2sGG4DKl3RoCU8stCEML8J5TY7RF683ZLTpIFoCh8IxGEYpmoPR8q U=; Authentication-Results: esa1.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa1.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa1.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa1.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa1.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa1.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa1.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: GsjU/RcR6AiK+7Kduvde5iFt+SCw1SEVd3/ghRbUnoBV34SqZZaRO1kMUmurqOBn6QqoHyII4E tvnZJg7mazZOCir5eGXqtZX+N62AoIItawmhoNMPe8/FI5XBLlngKtdtrjBFGbgMea593aAEAf qiXHG+1yUoBsoMksAo9TPQ2rGfj84XlMfHMoFp3oH21vO9rltIBEbzyx4m0g0p5xbEX8Q/Lptm 6Rib95iwy8q3WZxMVzjKS/KfX1zGtzeZ5dgxi3tTBqfe/etAU0nbHOE8HlAlVBU6FeBQaaFVVZ zpY= X-SBRS: 2.7 X-MesageID: 15137743 X-Ironport-Server: esa1.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.72,327,1580792400"; d="scan'208";a="15137743" From: Andrew Cooper To: Xen-devel Subject: [PATCH 01/11] x86/ucode/amd: Fix more potential buffer overruns with microcode parsing Date: Tue, 31 Mar 2020 11:05:21 +0100 Message-ID: <20200331100531.4294-2-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200331100531.4294-1-andrew.cooper3@citrix.com> References: <20200331100531.4294-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper , Wei Liu , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" cpu_request_microcode() doesn't know the buffer is at least 4 bytes long before inspecting UCODE_MAGIC. install_equiv_cpu_table() doesn't know the boundary of the buffer it is interpreting as an equivalency table. This case was clearly observed at one point in the past, given the subsequent overrun detection, but without comprehending that the damage was already done. Make the logic consistent with container_fast_forward() and pass size_left in to install_equiv_cpu_table(). Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- CC: Jan Beulich CC: Wei Liu CC: Roger Pau Monné --- xen/arch/x86/cpu/microcode/amd.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/xen/arch/x86/cpu/microcode/amd.c b/xen/arch/x86/cpu/microcode/amd.c index 6bf3a054d3..796745e928 100644 --- a/xen/arch/x86/cpu/microcode/amd.c +++ b/xen/arch/x86/cpu/microcode/amd.c @@ -303,11 +303,20 @@ static int get_ucode_from_buffer_amd( static int install_equiv_cpu_table( struct microcode_amd *mc_amd, const void *data, + size_t size_left, size_t *offset) { - const struct mpbhdr *mpbuf = data + *offset + 4; + const struct mpbhdr *mpbuf; const struct equiv_cpu_entry *eq; + if ( size_left < (sizeof(*mpbuf) + 4) || + (mpbuf = data + *offset + 4, + size_left - sizeof(*mpbuf) - 4 < mpbuf->len) ) + { + printk(XENLOG_WARNING "microcode: No space for equivalent cpu table\n"); + return -EINVAL; + } + *offset += mpbuf->len + CONT_HDR_SIZE; /* add header length */ if ( mpbuf->type != UCODE_EQUIV_CPU_TABLE_TYPE ) @@ -417,7 +426,8 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, current_cpu_id = cpuid_eax(0x00000001); - if ( *(const uint32_t *)buf != UCODE_MAGIC ) + if ( bufsize < 4 || + *(const uint32_t *)buf != UCODE_MAGIC ) { printk(KERN_ERR "microcode: Wrong microcode patch file magic\n"); error = -EINVAL; @@ -447,24 +457,13 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, */ while ( offset < bufsize ) { - error = install_equiv_cpu_table(mc_amd, buf, &offset); + error = install_equiv_cpu_table(mc_amd, buf, bufsize - offset, &offset); if ( error ) { printk(KERN_ERR "microcode: installing equivalent cpu table failed\n"); break; } - /* - * Could happen as we advance 'offset' early - * in install_equiv_cpu_table - */ - if ( offset > bufsize ) - { - printk(KERN_ERR "microcode: Microcode buffer overrun\n"); - error = -EINVAL; - break; - } - if ( find_equiv_cpu_id(mc_amd->equiv_cpu_table, current_cpu_id, &equiv_cpu_id) ) break; From patchwork Tue Mar 31 10:05:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11467203 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id F2C6692C for ; Tue, 31 Mar 2020 10:06:42 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id CF530206DB for ; Tue, 31 Mar 2020 10:06:42 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="fxXpXhkV" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CF530206DB Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jJDmB-0005l4-QC; Tue, 31 Mar 2020 10:05:43 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jJDmA-0005ks-5q for xen-devel@lists.xenproject.org; Tue, 31 Mar 2020 10:05:42 +0000 X-Inumbo-ID: 2d0859e4-7337-11ea-9e09-bc764e2007e4 Received: from esa1.hc3370-68.iphmx.com (unknown [216.71.145.142]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 2d0859e4-7337-11ea-9e09-bc764e2007e4; Tue, 31 Mar 2020 10:05:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1585649141; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=YrG44H+CYGRviPo/ndiitW+LLJDRrPAH2vHY+mcBUIo=; b=fxXpXhkVxy6mVapHORamXW8GSTNu+S0cFVlzlo9JR8Ztfp1BM6jVYtZt dJfh1Fh+3UA+8OMhIvQghpjRkKFTDwIU0vyE30G0MFMD+jj6Tgs54ERev HHJjIikgH0ajpo3MUWlIllBV+yg2vmfekDoozwcAw7m956cJhZRfmz8Ee s=; Authentication-Results: esa1.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa1.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa1.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa1.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa1.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa1.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa1.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: 7FRmpTh4yVi1pDjh84ntX64i9zsagK/QT7mtQQin26D0N3Mo8o5NcnBTf40mIR0RGTwpGiAz2h lcptSO7lxgHheN3+sGIFYsK97yOaRJGaf/u30pUptZYPCN/OQKdaPRpUtT+cxmdjmSfyt9oXj1 ca0KLClhQnxTndrqJIVYmqgSuf0R8u25Yq2aLbuVxQSBG+ZUA/oGI3fLztK6Yb4hhAx9QRjbb6 qlEIjnK/hhI+Ne/jFzby6OCVa127qsYVr4imi2tyBvPL07ciGVrNjWLeZPPPwl9qUuYLvR1jPp BPI= X-SBRS: 2.7 X-MesageID: 15137744 X-Ironport-Server: esa1.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.72,327,1580792400"; d="scan'208";a="15137744" From: Andrew Cooper To: Xen-devel Subject: [PATCH 02/11] x86/ucode/amd: Move check_final_patch_levels() to apply_microcode() Date: Tue, 31 Mar 2020 11:05:22 +0100 Message-ID: <20200331100531.4294-3-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200331100531.4294-1-andrew.cooper3@citrix.com> References: <20200331100531.4294-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper , Wei Liu , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" The microcode revision of whichever CPU runs cpu_request_microcode() is not necessarily applicable to other CPUs. If the BIOS left us with asymmetric microcode, rejecting updates in cpu_request_microcode() would prevent us levelling the system even if only up to the final level. Also, failing to cache microcode misses an opportunity to get beyond the final level via the S3 path. Move check_final_patch_levels() earlier and use it in apply_microcode(). Reword the error message to be more informative, and use -ENXIO as this corner case has nothing to do with permissions. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- CC: Jan Beulich CC: Wei Liu CC: Roger Pau Monné --- xen/arch/x86/cpu/microcode/amd.c | 83 ++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 45 deletions(-) diff --git a/xen/arch/x86/cpu/microcode/amd.c b/xen/arch/x86/cpu/microcode/amd.c index 796745e928..4245dc13bb 100644 --- a/xen/arch/x86/cpu/microcode/amd.c +++ b/xen/arch/x86/cpu/microcode/amd.c @@ -119,6 +119,36 @@ static bool_t verify_patch_size(uint32_t patch_size) return (patch_size <= max_size); } +static bool check_final_patch_levels(const struct cpu_signature *sig) +{ + /* + * The 'final_levels' of patch ids have been obtained empirically. + * Refer bug https://bugzilla.suse.com/show_bug.cgi?id=913996 + * for details of the issue. The short version is that people + * using certain Fam10h systems noticed system hang issues when + * trying to update microcode levels beyond the patch IDs below. + * From internal discussions, we gathered that OS/hypervisor + * cannot reliably perform microcode updates beyond these levels + * due to hardware issues. Therefore, we need to abort microcode + * update process if we hit any of these levels. + */ + static const unsigned int final_levels[] = { + 0x01000098, + 0x0100009f, + 0x010000af, + }; + unsigned int i; + + if ( boot_cpu_data.x86 != 0x10 ) + return false; + + for ( i = 0; i < ARRAY_SIZE(final_levels); i++ ) + if ( sig->rev == final_levels[i] ) + return true; + + return false; +} + static bool_t find_equiv_cpu_id(const struct equiv_cpu_entry *equiv_cpu_table, unsigned int current_cpu_id, unsigned int *equiv_cpu_id) @@ -229,6 +259,14 @@ static int apply_microcode(const struct microcode_patch *patch) if ( !match_cpu(patch) ) return -EINVAL; + if ( check_final_patch_levels(sig) ) + { + printk(XENLOG_ERR + "microcode: CPU%u current rev %#x unsafe to update\n", + cpu, sig->rev); + return -ENXIO; + } + hdr = patch->mpb; hw_err = wrmsr_safe(MSR_AMD_PATCHLOADER, (unsigned long)hdr); @@ -374,43 +412,6 @@ static int container_fast_forward(const void *data, size_t size_left, size_t *of return 0; } -/* - * The 'final_levels' of patch ids have been obtained empirically. - * Refer bug https://bugzilla.suse.com/show_bug.cgi?id=913996 - * for details of the issue. The short version is that people - * using certain Fam10h systems noticed system hang issues when - * trying to update microcode levels beyond the patch IDs below. - * From internal discussions, we gathered that OS/hypervisor - * cannot reliably perform microcode updates beyond these levels - * due to hardware issues. Therefore, we need to abort microcode - * update process if we hit any of these levels. - */ -static const unsigned int final_levels[] = { - 0x01000098, - 0x0100009f, - 0x010000af -}; - -static bool_t check_final_patch_levels(unsigned int cpu) -{ - /* - * Check the current patch levels on the cpu. If they are equal to - * any of the 'final_levels', then we should not update the microcode - * patch on the cpu as system will hang otherwise. - */ - const struct cpu_signature *sig = &per_cpu(cpu_sig, cpu); - unsigned int i; - - if ( boot_cpu_data.x86 != 0x10 ) - return 0; - - for ( i = 0; i < ARRAY_SIZE(final_levels); i++ ) - if ( sig->rev == final_levels[i] ) - return 1; - - return 0; -} - static struct microcode_patch *cpu_request_microcode(const void *buf, size_t bufsize) { @@ -434,14 +435,6 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, goto out; } - if ( check_final_patch_levels(cpu) ) - { - printk(XENLOG_INFO - "microcode: Cannot update microcode patch on the cpu as we hit a final level\n"); - error = -EPERM; - goto out; - } - mc_amd = xzalloc(struct microcode_amd); if ( !mc_amd ) { From patchwork Tue Mar 31 10:05:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11467201 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C263A81 for ; Tue, 31 Mar 2020 10:06:40 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 9EB75206DB for ; Tue, 31 Mar 2020 10:06:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="TJIT5i2P" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9EB75206DB Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jJDmG-0005nQ-Fv; Tue, 31 Mar 2020 10:05:48 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jJDmF-0005mq-44 for xen-devel@lists.xenproject.org; Tue, 31 Mar 2020 10:05:47 +0000 X-Inumbo-ID: 2e02c064-7337-11ea-9e09-bc764e2007e4 Received: from esa1.hc3370-68.iphmx.com (unknown [216.71.145.142]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 2e02c064-7337-11ea-9e09-bc764e2007e4; Tue, 31 Mar 2020 10:05:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1585649142; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=9rWh21Edfez0ICixkeL7P6zQBmZ5AXXQhVFZulp9HhE=; b=TJIT5i2PD2hop2Pn30ujfzHNt3RT/HgAHa7ygExr3XOG0DbgS1ViTw7I DDRySxDMnd73h6aeFQXB3oR6HyGJATPl/tS/tU3Y3lDPR/1y/c++I9k9T aC/qNykfJDQnR+tMjhzgvVSlgG0dHb5MBB4hTDMxJUjSyQxJYHJWqe+D5 g=; Authentication-Results: esa1.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa1.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa1.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa1.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa1.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa1.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa1.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: fouPiB5QEAFmQEUiSB7PoZkrziHhhGN70grod24TSPxibw4x7WBBOAdgEj/UqA7wa7qHNlrOAE SPY2+5zpmDB6COa54JgN8NNaKsVhYlQlIv5lvAeFKzXGZtXQ445DfQmRXCNIiovdYQAccaYmNK VPwOi9LBYlWo+THrSpehOq5UCr6td/7mjBUp0VquBWpO3xdHP4+i/OhXJO9q4104HnNZYpHbZR P4cQBhiZK2qsu/Yb+bA6T6GQjgRc7H3iAWQh26wS2FbtB3/hlFIFtPYjvsDUV+Ih0Y+Zd7zIhb ugY= X-SBRS: 2.7 X-MesageID: 15137745 X-Ironport-Server: esa1.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.72,327,1580792400"; d="scan'208";a="15137745" From: Andrew Cooper To: Xen-devel Subject: [PATCH 03/11] x86/ucode/amd: Don't use void * for microcode_patch->mpb Date: Tue, 31 Mar 2020 11:05:23 +0100 Message-ID: <20200331100531.4294-4-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200331100531.4294-1-andrew.cooper3@citrix.com> References: <20200331100531.4294-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper , Wei Liu , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" All code works fine with it having its correct type, and it even allows us to drop two casts in a printk(). No functional change. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- CC: Jan Beulich CC: Wei Liu CC: Roger Pau Monné --- xen/arch/x86/cpu/microcode/amd.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/cpu/microcode/amd.c b/xen/arch/x86/cpu/microcode/amd.c index 4245dc13bb..3f3a05fad2 100644 --- a/xen/arch/x86/cpu/microcode/amd.c +++ b/xen/arch/x86/cpu/microcode/amd.c @@ -59,7 +59,7 @@ struct __packed microcode_header_amd { #define UCODE_UCODE_TYPE 0x00000001 struct microcode_patch { - void *mpb; + struct microcode_header_amd *mpb; size_t mpb_size; struct equiv_cpu_entry *equiv_cpu_table; size_t equiv_cpu_table_size; @@ -330,8 +330,7 @@ static int get_ucode_from_buffer_amd( pr_debug("microcode: CPU%d size %zu, block size %u offset %zu equivID %#x rev %#x\n", smp_processor_id(), bufsize, mpbuf->len, *offset, - ((struct microcode_header_amd *)mc_amd->mpb)->processor_rev_id, - ((struct microcode_header_amd *)mc_amd->mpb)->patch_id); + mc_amd->mpb->processor_rev_id, mc_amd->mpb->patch_id); *offset += mpbuf->len + SECTION_HDR_SIZE; From patchwork Tue Mar 31 10:05:24 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11467207 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6D48981 for ; Tue, 31 Mar 2020 10:06:48 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 4A086206DB for ; Tue, 31 Mar 2020 10:06:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="hIvbH5wy" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4A086206DB Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jJDmL-0005qV-2g; Tue, 31 Mar 2020 10:05:53 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jJDmK-0005pv-3t for xen-devel@lists.xenproject.org; Tue, 31 Mar 2020 10:05:52 +0000 X-Inumbo-ID: 31a5b08c-7337-11ea-b4f4-bc764e2007e4 Received: from esa2.hc3370-68.iphmx.com (unknown [216.71.145.153]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 31a5b08c-7337-11ea-b4f4-bc764e2007e4; Tue, 31 Mar 2020 10:05:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1585649149; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=tMB7T+dj7zC/QyKtt2kmS9SEaLLZn8QGcuALGV7Ulcc=; b=hIvbH5wyN7xTQP6sYk8L6QtGQNfwh2j87otNW3WprDFgt4IIVgH5fC01 2vCgL0HV4lxz1ZB8Mm5DCThAVPKvxo4CiriWd3Vy5/YJCCrEo1wfqol2Z qASwgFn5T3rtfdJwlmKArOq43D/k5y94IdBQ1BAKmuSzwCzoDkoMDyX5S 8=; Authentication-Results: esa2.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa2.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa2.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa2.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa2.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa2.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa2.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: OZvT4CtbzMC6atAegqKPQ/qTtEDz+nCE6LA1IKEpiAamEE2Zix31WH7hbguAZ9KRMr+humNlLc WRQOOCCY8oAnc72tqfvjkO5D2x8KZ+o6MUOcfixUKkxnP5RrGuS33tMVAh2+uHJbbDV12EDl/d AYx9ALHWQHSZcmVgLvqhOzq2RrirjxK8FzW0hsAlFMA2I9ZFucS0/gdIp6QN7W4b54/xy/+n15 uLcMnbQAXbKVJGjfvT56Le6OQGeoC/ywgkW22k8S3ezi666OMdXzGdElii9YK734T6gomiIZuG GI8= X-SBRS: 2.7 X-MesageID: 14930059 X-Ironport-Server: esa2.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.72,327,1580792400"; d="scan'208";a="14930059" From: Andrew Cooper To: Xen-devel Subject: [PATCH 04/11] x86/ucode/amd: Collect CPUID.1.EAX in collect_cpu_info() Date: Tue, 31 Mar 2020 11:05:24 +0100 Message-ID: <20200331100531.4294-5-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200331100531.4294-1-andrew.cooper3@citrix.com> References: <20200331100531.4294-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper , Wei Liu , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" ... rather than collecting it repeatedly in microcode_fits(). This brings the behaviour in line with the Intel side. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- CC: Jan Beulich CC: Wei Liu CC: Roger Pau Monné --- xen/arch/x86/cpu/microcode/amd.c | 11 +++-------- xen/include/asm-x86/microcode.h | 2 +- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/xen/arch/x86/cpu/microcode/amd.c b/xen/arch/x86/cpu/microcode/amd.c index 3f3a05fad2..d2ecc7ae87 100644 --- a/xen/arch/x86/cpu/microcode/amd.c +++ b/xen/arch/x86/cpu/microcode/amd.c @@ -79,6 +79,7 @@ static int collect_cpu_info(struct cpu_signature *csig) { memset(csig, 0, sizeof(*csig)); + csig->sig = cpuid_eax(1); rdmsrl(MSR_AMD_PATCHLEVEL, csig->rev); pr_debug("microcode: CPU%d collect_cpu_info: patch_id=%#x\n", @@ -177,12 +178,9 @@ static enum microcode_match_result microcode_fits( const struct cpu_signature *sig = &per_cpu(cpu_sig, cpu); const struct microcode_header_amd *mc_header = mc_amd->mpb; const struct equiv_cpu_entry *equiv_cpu_table = mc_amd->equiv_cpu_table; - unsigned int current_cpu_id; unsigned int equiv_cpu_id; - current_cpu_id = cpuid_eax(0x00000001); - - if ( !find_equiv_cpu_id(equiv_cpu_table, current_cpu_id, &equiv_cpu_id) ) + if ( !find_equiv_cpu_id(equiv_cpu_table, sig->sig, &equiv_cpu_id) ) return MIS_UCODE; if ( (mc_header->processor_rev_id) != equiv_cpu_id ) @@ -419,13 +417,10 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, struct microcode_patch *patch = NULL; size_t offset = 0, saved_size = 0; int error = 0; - unsigned int current_cpu_id; unsigned int equiv_cpu_id; unsigned int cpu = smp_processor_id(); const struct cpu_signature *sig = &per_cpu(cpu_sig, cpu); - current_cpu_id = cpuid_eax(0x00000001); - if ( bufsize < 4 || *(const uint32_t *)buf != UCODE_MAGIC ) { @@ -456,7 +451,7 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, break; } - if ( find_equiv_cpu_id(mc_amd->equiv_cpu_table, current_cpu_id, + if ( find_equiv_cpu_id(mc_amd->equiv_cpu_table, sig->sig, &equiv_cpu_id) ) break; diff --git a/xen/include/asm-x86/microcode.h b/xen/include/asm-x86/microcode.h index 3a8e4e8221..cbbe28cb45 100644 --- a/xen/include/asm-x86/microcode.h +++ b/xen/include/asm-x86/microcode.h @@ -7,7 +7,7 @@ #include struct cpu_signature { - /* CPU signature (CPUID.1.EAX). Only written on Intel. */ + /* CPU signature (CPUID.1.EAX). */ unsigned int sig; /* Platform Flags. Only applicable to Intel. */ From patchwork Tue Mar 31 10:05:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11467205 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 190B992C for ; Tue, 31 Mar 2020 10:06:46 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id E931B206DB for ; Tue, 31 Mar 2020 10:06:45 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="MlS1y7Zz" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E931B206DB Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jJDmI-0005p0-Pu; Tue, 31 Mar 2020 10:05:50 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jJDmH-0005o6-8x for xen-devel@lists.xenproject.org; Tue, 31 Mar 2020 10:05:49 +0000 X-Inumbo-ID: 2f649310-7337-11ea-ba0b-12813bfff9fa Received: from esa5.hc3370-68.iphmx.com (unknown [216.71.155.168]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 2f649310-7337-11ea-ba0b-12813bfff9fa; Tue, 31 Mar 2020 10:05:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1585649144; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=4Rpc+u7yewDKCwasBqxPdMtiKb7w5ItgKOuQREKX64k=; b=MlS1y7ZzkI85eiQiiHF4PvDTodsN3LztDnH5CuKnTHkRUQYENuyji75d +MaWKOpRyneaF1hTBZgAW/92FlEHCM68+SpPYQXfi8PIA/3IMND00yH/F VFGve12kTHcHuxYK3pCu37j22yoXns4Pi1vgDWXcDt8m3EZMElPU9Plw+ s=; Authentication-Results: esa5.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa5.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: tW0ZKWaHqITBnQUfNXWyyeP5LgTUL9itJB1I3I63diIB+Q8ORzkjBwhZtdumqQDWN86wXLJjNp rdb7qQ/gRgIOdSjlcP3qkNnHZyYaEXJRI0Jx/noDsFH5SUtpGWYKWIZRoblGGoOND45AxfELHp Pu3i9lM52Exgeu5hggS0oLBy4Z9dFqfiFAJ3hYPRf8YMPFr4cBSz7YEcuH5SQzik5+N5ZHGike +ACKIH83Fa83xxch6md5Svpe0Yd4edwCyPSvYqyTWRNJ3+EscP5qVeXEMwH4GQsiPybmX7X57K NPk= X-SBRS: 2.7 X-MesageID: 15245336 X-Ironport-Server: esa5.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.72,327,1580792400"; d="scan'208";a="15245336" From: Andrew Cooper To: Xen-devel Subject: [PATCH 05/11] x86/ucode/amd: Overhaul the equivalent cpu table handling completely Date: Tue, 31 Mar 2020 11:05:25 +0100 Message-ID: <20200331100531.4294-6-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200331100531.4294-1-andrew.cooper3@citrix.com> References: <20200331100531.4294-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper , Wei Liu , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" We currently copy the entire equivalency table, and the single correct microcode. This is not safe to heterogeneous scenarios, and as Xen doesn't support such situations to being with, can be used to simplify things further. The CPUID.1.EAX => processor_rev_id mapping is fixed for an individual part. We can cache the single appropriate entry on first discovery, and forgo duplicating the entire table. Alter install_equiv_cpu_table() to be scan_equiv_cpu_table() which is responsible for checking the equivalency table and caching appropriate details. It now has a check for finding a different mapping (which indicates that one of the tables we've seen is definitely wrong). A return value of -ESRCH is now used to signify "everything fine, but nothing applicable for the current CPU", which is used to select the container_fast_forward() path. Drop the printk(), as each applicable error path in scan_equiv_cpu_table() already prints diagnostics. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- CC: Jan Beulich CC: Wei Liu CC: Roger Pau Monné Naming of 'equiv' subject to improvement. An alternative would be to embed the full equivelancy table, but it is fairly large, and would need adjusting every time a new model/stepping was released. --- xen/arch/x86/cpu/microcode/amd.c | 112 ++++++++++++++++++++++----------------- 1 file changed, 64 insertions(+), 48 deletions(-) diff --git a/xen/arch/x86/cpu/microcode/amd.c b/xen/arch/x86/cpu/microcode/amd.c index d2ecc7ae87..d3439b0c6c 100644 --- a/xen/arch/x86/cpu/microcode/amd.c +++ b/xen/arch/x86/cpu/microcode/amd.c @@ -61,8 +61,6 @@ struct __packed microcode_header_amd { struct microcode_patch { struct microcode_header_amd *mpb; size_t mpb_size; - struct equiv_cpu_entry *equiv_cpu_table; - size_t equiv_cpu_table_size; }; /* Temporary, until the microcode_* structure are disentangled. */ @@ -74,6 +72,31 @@ struct mpbhdr { uint8_t data[]; }; +/* + * Microcode updates for different CPUs are distinguished by their + * processor_rev_id in the header. This denotes the format of the internals + * of the microcode engine, and is fixed for an individual CPU. + * + * There is a mapping from the CPU signature (CPUID.1.EAX - + * family/model/stepping) to the "equivalent CPU identifier" which is + * similarly fixed. In some cases, multiple different CPU signatures map to + * the same equiv_id for processor lines which share identical microcode + * facilities. + * + * This mapping can't be calculated in the general case, but is provided in + * the microcode container, so the correct piece of microcode for the CPU can + * be identified. We cache it the first time we encounter the correct mapping + * for this system. + * + * Note: for now, we assume a fully homogeneous setup, meaning that there is + * exactly one equiv_id we need to worry about for microcode blob + * identification. This may need revisiting in due course. + */ +static struct { + uint32_t sig; + uint16_t id; +} equiv __read_mostly; + /* See comment in start_update() for cases when this routine fails */ static int collect_cpu_info(struct cpu_signature *csig) { @@ -150,40 +173,15 @@ static bool check_final_patch_levels(const struct cpu_signature *sig) return false; } -static bool_t find_equiv_cpu_id(const struct equiv_cpu_entry *equiv_cpu_table, - unsigned int current_cpu_id, - unsigned int *equiv_cpu_id) -{ - unsigned int i; - - if ( !equiv_cpu_table ) - return 0; - - for ( i = 0; equiv_cpu_table[i].installed_cpu != 0; i++ ) - { - if ( current_cpu_id == equiv_cpu_table[i].installed_cpu ) - { - *equiv_cpu_id = equiv_cpu_table[i].equiv_cpu & 0xffff; - return 1; - } - } - - return 0; -} - static enum microcode_match_result microcode_fits( const struct microcode_amd *mc_amd) { unsigned int cpu = smp_processor_id(); const struct cpu_signature *sig = &per_cpu(cpu_sig, cpu); const struct microcode_header_amd *mc_header = mc_amd->mpb; - const struct equiv_cpu_entry *equiv_cpu_table = mc_amd->equiv_cpu_table; - unsigned int equiv_cpu_id; - if ( !find_equiv_cpu_id(equiv_cpu_table, sig->sig, &equiv_cpu_id) ) - return MIS_UCODE; - - if ( (mc_header->processor_rev_id) != equiv_cpu_id ) + if ( equiv.sig != sig->sig || + equiv.id != mc_header->processor_rev_id ) return MIS_UCODE; if ( !verify_patch_size(mc_amd->mpb_size) ) @@ -213,7 +211,6 @@ static void free_patch(struct microcode_patch *mc_amd) { if ( mc_amd ) { - xfree(mc_amd->equiv_cpu_table); xfree(mc_amd->mpb); xfree(mc_amd); } @@ -335,14 +332,15 @@ static int get_ucode_from_buffer_amd( return 0; } -static int install_equiv_cpu_table( - struct microcode_amd *mc_amd, +static int scan_equiv_cpu_table( const void *data, size_t size_left, size_t *offset) { + const struct cpu_signature *sig = &this_cpu(cpu_sig); const struct mpbhdr *mpbuf; const struct equiv_cpu_entry *eq; + unsigned int i, nr; if ( size_left < (sizeof(*mpbuf) + 4) || (mpbuf = data + *offset + 4, @@ -362,19 +360,45 @@ static int install_equiv_cpu_table( if ( mpbuf->len == 0 || mpbuf->len % sizeof(*eq) || (eq = (const void *)mpbuf->data, - eq[(mpbuf->len / sizeof(*eq)) - 1].installed_cpu) ) + nr = mpbuf->len / sizeof(*eq), + eq[nr - 1].installed_cpu) ) { printk(KERN_ERR "microcode: Wrong microcode equivalent cpu table length\n"); return -EINVAL; } - mc_amd->equiv_cpu_table = xmemdup_bytes(mpbuf->data, mpbuf->len); - if ( !mc_amd->equiv_cpu_table ) - return -ENOMEM; + /* Search the equiv_cpu_table for the current CPU. */ + for ( i = 0; i < nr && eq[i].installed_cpu; ++i ) + { + if ( eq[i].installed_cpu != sig->sig ) + continue; - mc_amd->equiv_cpu_table_size = mpbuf->len; + if ( !equiv.sig ) /* Cache details on first find. */ + { + equiv.sig = sig->sig; + equiv.id = eq[i].equiv_cpu; + return 0; + } - return 0; + if ( equiv.sig != sig->sig || equiv.id != eq[i].equiv_cpu ) + { + /* + * This can only occur if two equiv tables have been seen with + * different mappings for the same CPU. The mapping is fixed, so + * one of the tables is wrong. As we can't calculate the mapping, + * we trusted the first table we saw. + */ + printk(XENLOG_ERR + "microcode: Equiv mismatch: cpu %08x, got %04x, cached %04x\n", + sig->sig, eq[i].equiv_cpu, equiv.id); + return -EINVAL; + } + + return 0; + } + + /* equiv_cpu_table was fine, but nothing found for the current CPU. */ + return -ESRCH; } static int container_fast_forward(const void *data, size_t size_left, size_t *offset) @@ -417,7 +441,6 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, struct microcode_patch *patch = NULL; size_t offset = 0, saved_size = 0; int error = 0; - unsigned int equiv_cpu_id; unsigned int cpu = smp_processor_id(); const struct cpu_signature *sig = &per_cpu(cpu_sig, cpu); @@ -444,15 +467,9 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, */ while ( offset < bufsize ) { - error = install_equiv_cpu_table(mc_amd, buf, bufsize - offset, &offset); - if ( error ) - { - printk(KERN_ERR "microcode: installing equivalent cpu table failed\n"); - break; - } + error = scan_equiv_cpu_table(buf, bufsize - offset, &offset); - if ( find_equiv_cpu_id(mc_amd->equiv_cpu_table, sig->sig, - &equiv_cpu_id) ) + if ( !error || error != -ESRCH ) break; error = container_fast_forward(buf, bufsize - offset, &offset); @@ -479,7 +496,6 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, if ( error == -ENODATA ) error = 0; - xfree(mc_amd->equiv_cpu_table); xfree(mc_amd); goto out; } From patchwork Tue Mar 31 10:05:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11467209 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 546D081 for ; Tue, 31 Mar 2020 10:06:53 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 2BF9C206DB for ; Tue, 31 Mar 2020 10:06:53 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="hXnV5v14" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2BF9C206DB Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jJDmN-0005si-Jr; Tue, 31 Mar 2020 10:05:55 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jJDmM-0005rq-95 for xen-devel@lists.xenproject.org; Tue, 31 Mar 2020 10:05:54 +0000 X-Inumbo-ID: 2f649312-7337-11ea-ba0b-12813bfff9fa Received: from esa5.hc3370-68.iphmx.com (unknown [216.71.155.168]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 2f649312-7337-11ea-ba0b-12813bfff9fa; Tue, 31 Mar 2020 10:05:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1585649145; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=bRv2ZDDEle7+rr6nLrEPeMqu4nRuzhy/4HYzc7luCQ8=; b=hXnV5v140EUolkCQLbiIo6Duo/L3K3E1vB9ozfLV8rhaBjnv0q5B6e8n OdknJXrMQBsE3r02JRkBsrt7y+H403wyp3Qx4QhI/YBlxOZjfDTyRJgJO MMR2qDiJggV5HdwTBe9O6/ijlTZFt/+MHj4BARRL+w0/MWXgst2N3EdNZ 4=; Authentication-Results: esa5.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa5.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa5.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa5.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: ImDgnuZpNV9ILuPcyTYVM1MpFFldmGAMbeW5w4EGwpxCKzxyTYxuIYz2YqlYKPTvaaEm4t6zI0 Q0qZrRefWytWnnS+IuibknspytIO9OQjI0RuHV7FY+oWyZ1KA4jJCpDUP8oVICDX/1ar+Oj1cA 7ftZVTeNZwS+edqdYJOOVzAGl876ghYuGOOgHteABnAtBLpbSwWMgJ5MMMI2jqe0x4iaLBIahz ePq4pFzPtlA2YBc5U3wqgRuYQqFXl6BIadfs6K3J4G5hrl3GZ/1TOLFXa2yLw6m3ktB2DruAWc SAo= X-SBRS: 2.7 X-MesageID: 15245337 X-Ironport-Server: esa5.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.72,327,1580792400"; d="scan'208";a="15245337" From: Andrew Cooper To: Xen-devel Subject: [PATCH 06/11] x86/ucode/amd: Move verify_patch_size() into get_ucode_from_buffer_amd() Date: Tue, 31 Mar 2020 11:05:26 +0100 Message-ID: <20200331100531.4294-7-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200331100531.4294-1-andrew.cooper3@citrix.com> References: <20200331100531.4294-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper , Wei Liu , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" We only stash the microcode blob size so it can be audited in microcode_fits(). However, the patch size check depends only on the CPU family. Move the check earlier to when we are parsing the container, which avoids caching bad microcode in the first place, and allows us to avoid storing the size at all. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- CC: Jan Beulich CC: Wei Liu CC: Roger Pau Monné --- xen/arch/x86/cpu/microcode/amd.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/xen/arch/x86/cpu/microcode/amd.c b/xen/arch/x86/cpu/microcode/amd.c index d3439b0c6c..8318664f85 100644 --- a/xen/arch/x86/cpu/microcode/amd.c +++ b/xen/arch/x86/cpu/microcode/amd.c @@ -60,7 +60,6 @@ struct __packed microcode_header_amd { struct microcode_patch { struct microcode_header_amd *mpb; - size_t mpb_size; }; /* Temporary, until the microcode_* structure are disentangled. */ @@ -184,12 +183,6 @@ static enum microcode_match_result microcode_fits( equiv.id != mc_header->processor_rev_id ) return MIS_UCODE; - if ( !verify_patch_size(mc_amd->mpb_size) ) - { - pr_debug("microcode: patch size mismatch\n"); - return MIS_UCODE; - } - if ( mc_header->patch_id <= sig->rev ) { pr_debug("microcode: patch is already at required level or greater.\n"); @@ -318,10 +311,15 @@ static int get_ucode_from_buffer_amd( return -EINVAL; } + if ( !verify_patch_size(mpbuf->len) ) + { + printk(XENLOG_ERR "microcode: patch size mismatch\n"); + return -EINVAL; + } + mc_amd->mpb = xmemdup_bytes(mpbuf->data, mpbuf->len); if ( !mc_amd->mpb ) return -ENOMEM; - mc_amd->mpb_size = mpbuf->len; pr_debug("microcode: CPU%d size %zu, block size %u offset %zu equivID %#x rev %#x\n", smp_processor_id(), bufsize, mpbuf->len, *offset, @@ -439,7 +437,7 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, struct microcode_amd *mc_amd; struct microcode_header_amd *saved = NULL; struct microcode_patch *patch = NULL; - size_t offset = 0, saved_size = 0; + size_t offset = 0; int error = 0; unsigned int cpu = smp_processor_id(); const struct cpu_signature *sig = &per_cpu(cpu_sig, cpu); @@ -516,7 +514,6 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, { xfree(saved); saved = mc_amd->mpb; - saved_size = mc_amd->mpb_size; } else { @@ -555,7 +552,6 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, if ( saved ) { mc_amd->mpb = saved; - mc_amd->mpb_size = saved_size; patch = mc_amd; } else From patchwork Tue Mar 31 10:05:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11467213 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EED9D92C for ; Tue, 31 Mar 2020 10:06:57 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id CBD90206DB for ; Tue, 31 Mar 2020 10:06:57 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="cdXGASeg" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org CBD90206DB Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jJDmS-0005wl-85; Tue, 31 Mar 2020 10:06:00 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jJDmR-0005vz-8z for xen-devel@lists.xenproject.org; Tue, 31 Mar 2020 10:05:59 +0000 X-Inumbo-ID: 2f649311-7337-11ea-ba0b-12813bfff9fa Received: from esa6.hc3370-68.iphmx.com (unknown [216.71.155.175]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 2f649311-7337-11ea-ba0b-12813bfff9fa; Tue, 31 Mar 2020 10:05:46 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1585649145; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Si5z3xeHwmyHLpHOIC9s/BWYm39Q13l64/PRkSlBm6w=; b=cdXGASegCVucSYjuDJm5B0j98ptJBbAJ3zNE/TLh0a8VTGZcrIKBSP4z bGueHDinyvfyv+GRoTeprjpiVeZqa+849+rNi9TiXOJdq8yDTkyLdectS J0zXuQViLtEM6TcAeUIGOb6XTosHkJ6uv8dTETiykoaWYf4pLrBEiyyCJ M=; Authentication-Results: esa6.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa6.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa6.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa6.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: XngBh1581dh7CTw+F+sgioVCiUhxNKM2+kaS9KN8JnNSqtxxjKjbDzVq7rVnR9HumtnbuKXHeQ UzlcYOVvpQgHaWTV8EAxW877G/NyR/XOB3cBvQZL4dRtmapIXFXi4fIqZaKif4gko4dONUdssA xBIbY7U2OnQ5nO5CvxEfChUHlw/6UFxsCjr/C8Y3D+rw3RH3TrHtJLV1ThkA8GTED1nwN5+HvA vtJKcuCRQ99yHnm1J/XL0wXM4cUxJtC+kQriDHXvyriFJc74aI2L6VWhLDexH1nESQn33RvTcn j9A= X-SBRS: 2.7 X-MesageID: 15327881 X-Ironport-Server: esa6.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.72,327,1580792400"; d="scan'208";a="15327881" From: Andrew Cooper To: Xen-devel Subject: [PATCH 07/11] x86/ucode/amd: Alter API for microcode_fits() Date: Tue, 31 Mar 2020 11:05:27 +0100 Message-ID: <20200331100531.4294-8-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200331100531.4294-1-andrew.cooper3@citrix.com> References: <20200331100531.4294-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper , Wei Liu , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Although it is logically a step in the wrong direction overall, it simplifies the rearranging of cpu_request_microcode() substantially for microcode_fits() to take struct microcode_header_amd directly, and not require an intermediate struct microcode_amd pointing at it. Make this change (taking time to rename 'mc_amd' to its eventual 'patch' to reduce the churn in the series), and a later cleanup will make it uniformly take a struct microcode_patch. No functional change. Signed-off-by: Andrew Cooper Acked-by: Jan Beulich --- CC: Jan Beulich CC: Wei Liu CC: Roger Pau Monné --- xen/arch/x86/cpu/microcode/amd.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/xen/arch/x86/cpu/microcode/amd.c b/xen/arch/x86/cpu/microcode/amd.c index 8318664f85..254f3dd4d7 100644 --- a/xen/arch/x86/cpu/microcode/amd.c +++ b/xen/arch/x86/cpu/microcode/amd.c @@ -173,31 +173,30 @@ static bool check_final_patch_levels(const struct cpu_signature *sig) } static enum microcode_match_result microcode_fits( - const struct microcode_amd *mc_amd) + const struct microcode_header_amd *patch) { unsigned int cpu = smp_processor_id(); const struct cpu_signature *sig = &per_cpu(cpu_sig, cpu); - const struct microcode_header_amd *mc_header = mc_amd->mpb; if ( equiv.sig != sig->sig || - equiv.id != mc_header->processor_rev_id ) + equiv.id != patch->processor_rev_id ) return MIS_UCODE; - if ( mc_header->patch_id <= sig->rev ) + if ( patch->patch_id <= sig->rev ) { pr_debug("microcode: patch is already at required level or greater.\n"); return OLD_UCODE; } pr_debug("microcode: CPU%d found a matching microcode update with version %#x (current=%#x)\n", - cpu, mc_header->patch_id, sig->rev); + cpu, patch->patch_id, sig->rev); return NEW_UCODE; } static bool match_cpu(const struct microcode_patch *patch) { - return patch && (microcode_fits(patch) == NEW_UCODE); + return patch && (microcode_fits(patch->mpb) == NEW_UCODE); } static void free_patch(struct microcode_patch *mc_amd) @@ -223,14 +222,11 @@ static enum microcode_match_result compare_header( static enum microcode_match_result compare_patch( const struct microcode_patch *new, const struct microcode_patch *old) { - const struct microcode_header_amd *new_header = new->mpb; - const struct microcode_header_amd *old_header = old->mpb; - /* Both patches to compare are supposed to be applicable to local CPU. */ - ASSERT(microcode_fits(new) != MIS_UCODE); - ASSERT(microcode_fits(old) != MIS_UCODE); + ASSERT(microcode_fits(new->mpb) != MIS_UCODE); + ASSERT(microcode_fits(old->mpb) != MIS_UCODE); - return compare_header(new_header, old_header); + return compare_header(new->mpb, old->mpb); } static int apply_microcode(const struct microcode_patch *patch) @@ -509,7 +505,7 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, * If the new ucode covers current CPU, compare ucodes and store the * one with higher revision. */ - if ( (microcode_fits(mc_amd) != MIS_UCODE) && + if ( (microcode_fits(mc_amd->mpb) != MIS_UCODE) && (!saved || (compare_header(mc_amd->mpb, saved) == NEW_UCODE)) ) { xfree(saved); From patchwork Tue Mar 31 10:05:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11467211 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AECF292C for ; Tue, 31 Mar 2020 10:06:56 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 8B6FE206DB for ; Tue, 31 Mar 2020 10:06:56 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="O5eQBmwE" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8B6FE206DB Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jJDmP-0005uk-Tb; Tue, 31 Mar 2020 10:05:57 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jJDmP-0005u6-3v for xen-devel@lists.xenproject.org; Tue, 31 Mar 2020 10:05:57 +0000 X-Inumbo-ID: 325bcb24-7337-11ea-b4f4-bc764e2007e4 Received: from esa2.hc3370-68.iphmx.com (unknown [216.71.145.153]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 325bcb24-7337-11ea-b4f4-bc764e2007e4; Tue, 31 Mar 2020 10:05:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1585649150; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=RXoGjwqxEgkEyP09KfWZrxI1cEHDPQ7pSyNUoM8V/OU=; b=O5eQBmwE5z3ShVtBnmfM6OMKB9FEn/LeTfHQkLZDVyHW1Kb8X630mQ0e KDFdRI82ifNX4qnhwAFcYhivCWIhC8pzZDCY9gG/gH3fsy2zCLk81ERlt 1GUk5dz0p3kb1jQjKntRJZ43QqsHPhdKzsp0yeJ0UJGYYSCEHp5mU/2RK M=; Authentication-Results: esa2.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa2.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa2.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa2.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa2.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa2.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa2.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: f0qRLIDg9nvm10rai68Kr+qGElZNeUi9y18eICqWyi4uC0gXeLuJXVrzW39CU0xLEiRnoUiBiW 2yn3ChCH3BEOQ90O/RLFjvkINEF3nTB80aEMb8MO5+KdppaAx1gJNFgpSmxyDQqurDuyAeIgzw Wvaas9WjzQJbWRyEj5vLKYrNoo1UFTO5/hiAq3cfGiXOj+ki+TBo97HcbNfm/FINvtMnLnbJSq cPTAl43CvCoi3tMUT8t3Jw54PlpgqH6RG+vSyaaMqtBp+wHvdORY4KPYZbdxxnFRn6l0sqVt2W jD0= X-SBRS: 2.7 X-MesageID: 14930060 X-Ironport-Server: esa2.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.72,327,1580792400"; d="scan'208";a="14930060" From: Andrew Cooper To: Xen-devel Subject: [PATCH 08/11] x86/ucode/amd: Rename bufsize to size in cpu_request_microcode() Date: Tue, 31 Mar 2020 11:05:28 +0100 Message-ID: <20200331100531.4294-9-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200331100531.4294-1-andrew.cooper3@citrix.com> References: <20200331100531.4294-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper , Wei Liu , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" To simplify future cleanup, rename this variable. No functional change. Signed-off-by: Andrew Cooper Acked-by: Jan Beulich --- CC: Jan Beulich CC: Wei Liu CC: Roger Pau Monné --- xen/arch/x86/cpu/microcode/amd.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/xen/arch/x86/cpu/microcode/amd.c b/xen/arch/x86/cpu/microcode/amd.c index 254f3dd4d7..980e61c547 100644 --- a/xen/arch/x86/cpu/microcode/amd.c +++ b/xen/arch/x86/cpu/microcode/amd.c @@ -427,8 +427,7 @@ static int container_fast_forward(const void *data, size_t size_left, size_t *of return 0; } -static struct microcode_patch *cpu_request_microcode(const void *buf, - size_t bufsize) +static struct microcode_patch *cpu_request_microcode(const void *buf, size_t size) { struct microcode_amd *mc_amd; struct microcode_header_amd *saved = NULL; @@ -438,7 +437,7 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, unsigned int cpu = smp_processor_id(); const struct cpu_signature *sig = &per_cpu(cpu_sig, cpu); - if ( bufsize < 4 || + if ( size < 4 || *(const uint32_t *)buf != UCODE_MAGIC ) { printk(KERN_ERR "microcode: Wrong microcode patch file magic\n"); @@ -459,17 +458,17 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, * 1. check if this container file has equiv_cpu_id match * 2. If not, fast-fwd to next container file */ - while ( offset < bufsize ) + while ( offset < size ) { - error = scan_equiv_cpu_table(buf, bufsize - offset, &offset); + error = scan_equiv_cpu_table(buf, size - offset, &offset); if ( !error || error != -ESRCH ) break; - error = container_fast_forward(buf, bufsize - offset, &offset); + error = container_fast_forward(buf, size - offset, &offset); if ( error == -ENODATA ) { - ASSERT(offset == bufsize); + ASSERT(offset == size); break; } if ( error ) @@ -498,7 +497,7 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, * It's possible the data file has multiple matching ucode, * lets keep searching till the latest version */ - while ( (error = get_ucode_from_buffer_amd(mc_amd, buf, bufsize, + while ( (error = get_ucode_from_buffer_amd(mc_amd, buf, size, &offset)) == 0 ) { /* @@ -517,7 +516,7 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, mc_amd->mpb = NULL; } - if ( offset >= bufsize ) + if ( offset >= size ) break; /* @@ -527,7 +526,7 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, * earlier while() (On this case, matches on earlier container * file and we break) * 3. Proceed to while ( (error = get_ucode_from_buffer_amd(mc_amd, - * buf, bufsize,&offset)) == 0 ) + * buf, size, &offset)) == 0 ) * 4. Find correct patch using microcode_fits() and apply the patch * (Assume: apply_microcode() is successful) * 5. The while() loop from (3) continues to parse the binary as @@ -540,7 +539,7 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, * before if ( mpbuf->type != UCODE_UCODE_TYPE ) evaluates to * false and returns -EINVAL. */ - if ( offset + SECTION_HDR_SIZE <= bufsize && + if ( offset + SECTION_HDR_SIZE <= size && *(const uint32_t *)(buf + offset) == UCODE_MAGIC ) break; } From patchwork Tue Mar 31 10:05:29 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11467215 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 40FFA81 for ; Tue, 31 Mar 2020 10:07:02 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 1CBA6206DB for ; Tue, 31 Mar 2020 10:07:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="eKhJ0VVA" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1CBA6206DB Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jJDmV-00060A-Hb; Tue, 31 Mar 2020 10:06:03 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jJDmU-0005yp-4u for xen-devel@lists.xenproject.org; Tue, 31 Mar 2020 10:06:02 +0000 X-Inumbo-ID: 3227e9c6-7337-11ea-b58d-bc764e2007e4 Received: from esa2.hc3370-68.iphmx.com (unknown [216.71.145.153]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 3227e9c6-7337-11ea-b58d-bc764e2007e4; Tue, 31 Mar 2020 10:05:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1585649150; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=+goJqvpvmGqGZD1x/qIZwuQWNz0zmMiWRwF4m9iscHc=; b=eKhJ0VVAV1TaBI9MvhxHTcgFa+ELfXerWO75cirO/DhJa53bZgthyOUJ MK1PYroG59fd9zyyICwX19um1mwrhOdwpN71xM4FXRK6qjKj4foK8VcZR T5U6TMvHyRgdK3NpT7qTCxoIvrg/8Iq3ls9b+9nTQWjejIYMrE+ZTVzpY 0=; Authentication-Results: esa2.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa2.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa2.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa2.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa2.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa2.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa2.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: O8X6k0mJS9C/QIl5W+npqArkraNq0mX+20v63LmYZsWDs904NWhswITkfkXddI7tvNKfraRhxQ GU66pbG20KrDBLKzW43RHNdWMi+Khh89aP8T4EQVMCPtfGZAsF1Grl+5LvoIbhvIyqg6BW8BOQ GoczDJx20uIfs2+Je3UIpp4FH987qlZSgul73fUwXmOMVzLGUdNzYbj5asRJZtc0sCC5Nt11yo 0jx8Xowb+9n96+EqqM3QejxNsUSUL4aYRBAOVCCyo6uAdyHc8j1ZUUFP6GZOEVT55cfHPunvwl SoY= X-SBRS: 2.7 X-MesageID: 14930062 X-Ironport-Server: esa2.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.72,327,1580792400"; d="scan'208";a="14930062" From: Andrew Cooper To: Xen-devel Subject: [PATCH 09/11] x86/ucode/amd: Remove gratuitous memory allocations from cpu_request_microcode() Date: Tue, 31 Mar 2020 11:05:29 +0100 Message-ID: <20200331100531.4294-10-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200331100531.4294-1-andrew.cooper3@citrix.com> References: <20200331100531.4294-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper , Wei Liu , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Just as on the Intel side, there is no point having get_ucode_from_buffer_amd() make $N memory allocations and free $N-1 of them. Delete get_ucode_from_buffer_amd() and rewrite the loop in cpu_request_microcode() to have 'saved' point into 'buf' until we finally decide to duplicate that blob and return it to our caller. Introduce a new struct container_microcode to simplify interpreting the container format. Doubly indent the logic to substantially reduce the churn in a later change. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- CC: Jan Beulich CC: Wei Liu CC: Roger Pau Monné --- xen/arch/x86/cpu/microcode/amd.c | 138 +++++++++++++-------------------------- 1 file changed, 47 insertions(+), 91 deletions(-) diff --git a/xen/arch/x86/cpu/microcode/amd.c b/xen/arch/x86/cpu/microcode/amd.c index 980e61c547..ae1276988f 100644 --- a/xen/arch/x86/cpu/microcode/amd.c +++ b/xen/arch/x86/cpu/microcode/amd.c @@ -70,6 +70,11 @@ struct mpbhdr { uint32_t len; uint8_t data[]; }; +struct container_microcode { + uint32_t type; /* UCODE_UCODE_TYPE */ + uint32_t len; + struct microcode_header_amd patch[]; +}; /* * Microcode updates for different CPUs are distinguished by their @@ -280,52 +285,6 @@ static int apply_microcode(const struct microcode_patch *patch) return 0; } -static int get_ucode_from_buffer_amd( - struct microcode_amd *mc_amd, - const void *buf, - size_t bufsize, - size_t *offset) -{ - const struct mpbhdr *mpbuf = buf + *offset; - - /* No more data */ - if ( *offset >= bufsize ) - { - printk(KERN_ERR "microcode: Microcode buffer overrun\n"); - return -EINVAL; - } - - if ( mpbuf->type != UCODE_UCODE_TYPE ) - { - printk(KERN_ERR "microcode: Wrong microcode payload type field\n"); - return -EINVAL; - } - - if ( (*offset + mpbuf->len) > bufsize ) - { - printk(KERN_ERR "microcode: Bad data in microcode data file\n"); - return -EINVAL; - } - - if ( !verify_patch_size(mpbuf->len) ) - { - printk(XENLOG_ERR "microcode: patch size mismatch\n"); - return -EINVAL; - } - - mc_amd->mpb = xmemdup_bytes(mpbuf->data, mpbuf->len); - if ( !mc_amd->mpb ) - return -ENOMEM; - - pr_debug("microcode: CPU%d size %zu, block size %u offset %zu equivID %#x rev %#x\n", - smp_processor_id(), bufsize, mpbuf->len, *offset, - mc_amd->mpb->processor_rev_id, mc_amd->mpb->patch_id); - - *offset += mpbuf->len + SECTION_HDR_SIZE; - - return 0; -} - static int scan_equiv_cpu_table( const void *data, size_t size_left, @@ -430,9 +389,9 @@ static int container_fast_forward(const void *data, size_t size_left, size_t *of static struct microcode_patch *cpu_request_microcode(const void *buf, size_t size) { struct microcode_amd *mc_amd; - struct microcode_header_amd *saved = NULL; + const struct microcode_header_amd *saved = NULL; struct microcode_patch *patch = NULL; - size_t offset = 0; + size_t offset = 0, saved_size = 0; int error = 0; unsigned int cpu = smp_processor_id(); const struct cpu_signature *sig = &per_cpu(cpu_sig, cpu); @@ -497,57 +456,54 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, size_t siz * It's possible the data file has multiple matching ucode, * lets keep searching till the latest version */ - while ( (error = get_ucode_from_buffer_amd(mc_amd, buf, size, - &offset)) == 0 ) + buf += offset; + size -= offset; { - /* - * If the new ucode covers current CPU, compare ucodes and store the - * one with higher revision. - */ - if ( (microcode_fits(mc_amd->mpb) != MIS_UCODE) && - (!saved || (compare_header(mc_amd->mpb, saved) == NEW_UCODE)) ) + while ( size ) { - xfree(saved); - saved = mc_amd->mpb; - } - else - { - xfree(mc_amd->mpb); - mc_amd->mpb = NULL; - } + const struct container_microcode *mc; + + if ( size < sizeof(*mc) || + (mc = buf)->type != UCODE_UCODE_TYPE || + size - sizeof(*mc) < mc->len || + !verify_patch_size(mc->len) ) + { + printk(XENLOG_ERR "microcode: Bad microcode data\n"); + error = -EINVAL; + break; + } - if ( offset >= size ) - break; + /* + * If the new ucode covers current CPU, compare ucodes and store the + * one with higher revision. + */ + if ( (microcode_fits(mc->patch) != MIS_UCODE) && + (!saved || (compare_header(mc->patch, saved) == NEW_UCODE)) ) + { + saved = mc->patch; + saved_size = mc->len; + } - /* - * 1. Given a situation where multiple containers exist and correct - * patch lives on a container that is not the last container. - * 2. We match equivalent ids using find_equiv_cpu_id() from the - * earlier while() (On this case, matches on earlier container - * file and we break) - * 3. Proceed to while ( (error = get_ucode_from_buffer_amd(mc_amd, - * buf, size, &offset)) == 0 ) - * 4. Find correct patch using microcode_fits() and apply the patch - * (Assume: apply_microcode() is successful) - * 5. The while() loop from (3) continues to parse the binary as - * there is a subsequent container file, but... - * 6. ...a correct patch can only be on one container and not on any - * subsequent ones. (Refer docs for more info) Therefore, we - * don't have to parse a subsequent container. So, we can abort - * the process here. - * 7. This ensures that we retain a success value (= 0) to 'error' - * before if ( mpbuf->type != UCODE_UCODE_TYPE ) evaluates to - * false and returns -EINVAL. - */ - if ( offset + SECTION_HDR_SIZE <= size && - *(const uint32_t *)(buf + offset) == UCODE_MAGIC ) - break; + /* Move over the microcode blob. */ + buf += sizeof(*mc) + mc->len; + size -= sizeof(*mc) + mc->len; + + /* + * Peek ahead. If we see the start of another container, we've + * exhaused all microcode blobs in this container. Exit cleanly. + */ + if ( size >= 4 && *(const uint32_t *)buf == UCODE_MAGIC ) + break; + } } if ( saved ) { - mc_amd->mpb = saved; - patch = mc_amd; + mc_amd->mpb = xmemdup_bytes(saved, saved_size); + if ( mc_amd->mpb ) + patch = mc_amd; + else + error = -ENOMEM; } else free_patch(mc_amd); From patchwork Tue Mar 31 10:05:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11467225 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4EA1492C for ; Tue, 31 Mar 2020 10:18:58 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id 2A3BD20848 for ; Tue, 31 Mar 2020 10:18:58 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="DjPTqiOa" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 2A3BD20848 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jJDxO-0007hy-DV; Tue, 31 Mar 2020 10:17:18 +0000 Received: from all-amaz-eas1.inumbo.com ([34.197.232.57] helo=us1-amaz-eas2.inumbo.com) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jJDxM-0007hr-JC for xen-devel@lists.xenproject.org; Tue, 31 Mar 2020 10:17:16 +0000 X-Inumbo-ID: cad688fc-7338-11ea-ba0b-12813bfff9fa Received: from esa2.hc3370-68.iphmx.com (unknown [216.71.145.153]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id cad688fc-7338-11ea-ba0b-12813bfff9fa; Tue, 31 Mar 2020 10:17:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1585649835; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=po0tW7uYDH8rZz1U6gCOAIBxov8htGafpY4XtbrzTHE=; b=DjPTqiOaOVD3eGFfaco9wXFG+fm+rb9cO/HBqoNQQfEHkPcrvimL112T khZocXLbQTUiAbCacF0aax/T9s7Ji0/dLdaunEV9OWbPwwZNS34Sr4Txg w/n9is/T2gj/7kUHIVOW9qyAn7qCI40z+bhVMSOsUz6wGvwZ+2tucxOz0 4=; Authentication-Results: esa2.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa2.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa2.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa2.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa2.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa2.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa2.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: yNroz7WDlU8XkXziXCuI82iaFPJ9aazBSU4hJsTJd2qhNs6I7t+KIYf9184EYwmJ4fzLn5QrZM SVeL9ag0ODI1G2m82A7MDtAjDPn4Lbop4WPpWwjm4DrTxEmsr+K1Z9h0/ftK2Tr+eVWMLopE9G 9KCHOluLYnhFDbwpplH3cuUUGjLUgPLcTwOMBOn1ir3BC8Uy0+DD0V0tm0VpLKz9YZYJwcbFr1 snW6o5Qu1S4VW4OjSsGsNpd1yyQUaV58t/V0nF8y45UbbOsUWgh4NoERB0CUnZT/C1bxC6HtbJ RAs= X-SBRS: 2.7 X-MesageID: 14930467 X-Ironport-Server: esa2.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.72,327,1580792400"; d="scan'208";a="14930467" From: Andrew Cooper To: Xen-devel Subject: [PATCH 10/11] x86/ucode/amd: Fold structures together Date: Tue, 31 Mar 2020 11:05:30 +0100 Message-ID: <20200331100531.4294-11-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200331100531.4294-1-andrew.cooper3@citrix.com> References: <20200331100531.4294-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper , Wei Liu , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" With all the necessary cleanup now in place, fold struct microcode_header_amd into struct microcode_patch and drop the struct microcode_amd temporary ifdef-ary. This removes the memory allocation of struct microcode_amd which is a single pointer to a separately allocated object, and therefore a waste. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- CC: Jan Beulich CC: Wei Liu CC: Roger Pau Monné --- xen/arch/x86/cpu/microcode/amd.c | 70 ++++++++++++---------------------------- 1 file changed, 20 insertions(+), 50 deletions(-) diff --git a/xen/arch/x86/cpu/microcode/amd.c b/xen/arch/x86/cpu/microcode/amd.c index ae1276988f..f9c50b43bf 100644 --- a/xen/arch/x86/cpu/microcode/amd.c +++ b/xen/arch/x86/cpu/microcode/amd.c @@ -37,7 +37,7 @@ struct __packed equiv_cpu_entry { uint16_t reserved; }; -struct __packed microcode_header_amd { +struct microcode_patch { uint32_t data_code; uint32_t patch_id; uint8_t mc_patch_data_id[2]; @@ -58,13 +58,6 @@ struct __packed microcode_header_amd { #define UCODE_EQUIV_CPU_TABLE_TYPE 0x00000000 #define UCODE_UCODE_TYPE 0x00000001 -struct microcode_patch { - struct microcode_header_amd *mpb; -}; - -/* Temporary, until the microcode_* structure are disentangled. */ -#define microcode_amd microcode_patch - struct mpbhdr { uint32_t type; uint32_t len; @@ -73,7 +66,7 @@ struct mpbhdr { struct container_microcode { uint32_t type; /* UCODE_UCODE_TYPE */ uint32_t len; - struct microcode_header_amd patch[]; + struct microcode_patch patch[]; }; /* @@ -178,7 +171,7 @@ static bool check_final_patch_levels(const struct cpu_signature *sig) } static enum microcode_match_result microcode_fits( - const struct microcode_header_amd *patch) + const struct microcode_patch *patch) { unsigned int cpu = smp_processor_id(); const struct cpu_signature *sig = &per_cpu(cpu_sig, cpu); @@ -201,37 +194,31 @@ static enum microcode_match_result microcode_fits( static bool match_cpu(const struct microcode_patch *patch) { - return patch && (microcode_fits(patch->mpb) == NEW_UCODE); + return patch && (microcode_fits(patch) == NEW_UCODE); } -static void free_patch(struct microcode_patch *mc_amd) +static void free_patch(struct microcode_patch *patch) { - if ( mc_amd ) - { - xfree(mc_amd->mpb); - xfree(mc_amd); - } + xfree(patch); } static enum microcode_match_result compare_header( - const struct microcode_header_amd *new_header, - const struct microcode_header_amd *old_header) + const struct microcode_patch *new, const struct microcode_patch *old) { - if ( new_header->processor_rev_id == old_header->processor_rev_id ) - return (new_header->patch_id > old_header->patch_id) ? NEW_UCODE - : OLD_UCODE; + if ( new->processor_rev_id != old->processor_rev_id ) + return MIS_UCODE; - return MIS_UCODE; + return new->patch_id > old->patch_id ? NEW_UCODE : OLD_UCODE; } static enum microcode_match_result compare_patch( const struct microcode_patch *new, const struct microcode_patch *old) { /* Both patches to compare are supposed to be applicable to local CPU. */ - ASSERT(microcode_fits(new->mpb) != MIS_UCODE); - ASSERT(microcode_fits(old->mpb) != MIS_UCODE); + ASSERT(microcode_fits(new) != MIS_UCODE); + ASSERT(microcode_fits(old) != MIS_UCODE); - return compare_header(new->mpb, old->mpb); + return compare_header(new, old); } static int apply_microcode(const struct microcode_patch *patch) @@ -239,7 +226,6 @@ static int apply_microcode(const struct microcode_patch *patch) int hw_err; unsigned int cpu = smp_processor_id(); struct cpu_signature *sig = &per_cpu(cpu_sig, cpu); - const struct microcode_header_amd *hdr; uint32_t rev, old_rev = sig->rev; if ( !patch ) @@ -256,9 +242,7 @@ static int apply_microcode(const struct microcode_patch *patch) return -ENXIO; } - hdr = patch->mpb; - - hw_err = wrmsr_safe(MSR_AMD_PATCHLOADER, (unsigned long)hdr); + hw_err = wrmsr_safe(MSR_AMD_PATCHLOADER, (unsigned long)patch); /* get patch id after patching */ rdmsrl(MSR_AMD_PATCHLEVEL, rev); @@ -268,14 +252,14 @@ static int apply_microcode(const struct microcode_patch *patch) * Some processors leave the ucode blob mapping as UC after the update. * Flush the mapping to regain normal cacheability. */ - flush_area_local(hdr, FLUSH_TLB_GLOBAL | FLUSH_ORDER(0)); + flush_area_local(patch, FLUSH_TLB_GLOBAL | FLUSH_ORDER(0)); /* check current patch id and patch's id for match */ - if ( hw_err || (rev != hdr->patch_id) ) + if ( hw_err || (rev != patch->patch_id) ) { printk(XENLOG_ERR "microcode: CPU%u update rev %#x to %#x failed, result %#x\n", - cpu, old_rev, hdr->patch_id, rev); + cpu, old_rev, patch->patch_id, rev); return -EIO; } @@ -388,8 +372,7 @@ static int container_fast_forward(const void *data, size_t size_left, size_t *of static struct microcode_patch *cpu_request_microcode(const void *buf, size_t size) { - struct microcode_amd *mc_amd; - const struct microcode_header_amd *saved = NULL; + const struct microcode_patch *saved = NULL; struct microcode_patch *patch = NULL; size_t offset = 0, saved_size = 0; int error = 0; @@ -404,14 +387,6 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, size_t siz goto out; } - mc_amd = xzalloc(struct microcode_amd); - if ( !mc_amd ) - { - printk(KERN_ERR "microcode: Cannot allocate memory for microcode patch\n"); - error = -ENOMEM; - goto out; - } - /* * Multiple container file support: * 1. check if this container file has equiv_cpu_id match @@ -448,7 +423,6 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, size_t siz if ( error == -ENODATA ) error = 0; - xfree(mc_amd); goto out; } @@ -499,14 +473,10 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, size_t siz if ( saved ) { - mc_amd->mpb = xmemdup_bytes(saved, saved_size); - if ( mc_amd->mpb ) - patch = mc_amd; - else + patch = xmemdup_bytes(saved, saved_size); + if ( !patch ) error = -ENOMEM; } - else - free_patch(mc_amd); out: if ( error && !patch ) From patchwork Tue Mar 31 10:05:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11467227 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EE1EC92C for ; Tue, 31 Mar 2020 10:19:10 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id C9FF820848 for ; Tue, 31 Mar 2020 10:19:10 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="aheJTwkn" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C9FF820848 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jJDxO-0007i7-MO; Tue, 31 Mar 2020 10:17:18 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jJDxO-0007hw-Ba for xen-devel@lists.xenproject.org; Tue, 31 Mar 2020 10:17:18 +0000 X-Inumbo-ID: cc17a1a6-7338-11ea-b58d-bc764e2007e4 Received: from esa3.hc3370-68.iphmx.com (unknown [216.71.145.155]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id cc17a1a6-7338-11ea-b58d-bc764e2007e4; Tue, 31 Mar 2020 10:17:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1585649838; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=HSKZ3OMvp/7K7T9ZRXW7lMybpFT8eMk17SlQVN7Z5zQ=; b=aheJTwknl03Q5IOfEipPXHSKSg4TTz80Bzn7CkgwUS3XjX8tFj0lvWe4 CLQMX6vlpE42l3LjmhD4qoKc+z8wYsyVsMu6JTdBYRuXIhzf/qy77tTvH EGZAD4bhk7+R240FwhLxkliKtahD8qaTo8vVSu3ttOzz0zQOh05x5JMH+ w=; Authentication-Results: esa3.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=andrew.cooper3@citrix.com; spf=Pass smtp.mailfrom=Andrew.Cooper3@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa3.hc3370-68.iphmx.com: no sender authenticity information available from domain of andrew.cooper3@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa3.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa3.hc3370-68.iphmx.com: domain of Andrew.Cooper3@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa3.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="Andrew.Cooper3@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa3.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa3.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: pdpA6ofa7fgicRboqqYoeuMfgs6cIv1oudwzviWO3E4dPHh0hNtxYlzFFsVtovVAKJ/Ud8jj93 8MzbvK+uEdd8jhcaBPHXmH+xwmrtWoZLdO4bTfOWBi+n8YSDtLW8IvFmJkuxYK/Gsmv3RtJwXe nxvymjK94KFWf+E0B8bJSViHt09HjOXTGIbmJsmMlujo/tSaN2r02m6N3eoKNQQklyxLpZn+yJ ySBHALfy5z/kJhWlG9PCHNRNV2GGfYj5icoDFKJRv9cwjNvDrh8MmkGdaI+ZwEzfMPCNkrKFVw 35g= X-SBRS: 2.7 X-MesageID: 14903418 X-Ironport-Server: esa3.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.72,327,1580792400"; d="scan'208";a="14903418" From: Andrew Cooper To: Xen-devel Subject: [PATCH 11/11] x86/ucode/amd: Rework parsing logic in cpu_request_microcode() Date: Tue, 31 Mar 2020 11:05:31 +0100 Message-ID: <20200331100531.4294-12-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200331100531.4294-1-andrew.cooper3@citrix.com> References: <20200331100531.4294-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Andrew Cooper , Wei Liu , Jan Beulich , =?utf-8?q?Roger_Pau_Monn=C3=A9?= Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" cpu_request_microcode() is still a confusing mess to follow, with sub functions responsible for maintaining offset. Rewrite it so all container structure handling is in this one function. Rewrite struct mpbhdr as struct container_equiv_table to aid parsing. Drop container_fast_forward() entirely, and shrink scan_equiv_cpu_table() to just its searching/caching logic. container_fast_forward() gets logically folded into the microcode blob scanning loop, except that a skip path is inserted, which is conditional on whether scan_equiv_cpu_table() thinks there is appropriate microcode to find. With this change, we now scan to the end of all provided microcode containers, and no longer give up at the first applicable one. Signed-off-by: Andrew Cooper Reviewed-by: Jan Beulich --- CC: Jan Beulich CC: Wei Liu CC: Roger Pau Monné --- xen/arch/x86/cpu/microcode/amd.c | 169 ++++++++++----------------------------- 1 file changed, 44 insertions(+), 125 deletions(-) diff --git a/xen/arch/x86/cpu/microcode/amd.c b/xen/arch/x86/cpu/microcode/amd.c index f9c50b43bf..0ada50797b 100644 --- a/xen/arch/x86/cpu/microcode/amd.c +++ b/xen/arch/x86/cpu/microcode/amd.c @@ -25,10 +25,6 @@ #define pr_debug(x...) ((void)0) -#define CONT_HDR_SIZE 12 -#define SECTION_HDR_SIZE 8 -#define PATCH_HDR_SIZE 32 - struct __packed equiv_cpu_entry { uint32_t installed_cpu; uint32_t fixed_errata_mask; @@ -58,10 +54,10 @@ struct microcode_patch { #define UCODE_EQUIV_CPU_TABLE_TYPE 0x00000000 #define UCODE_UCODE_TYPE 0x00000001 -struct mpbhdr { - uint32_t type; +struct container_equiv_table { + uint32_t type; /* UCODE_EQUIV_CPU_TABLE_TYPE */ uint32_t len; - uint8_t data[]; + struct equiv_cpu_entry eq[]; }; struct container_microcode { uint32_t type; /* UCODE_UCODE_TYPE */ @@ -269,55 +265,25 @@ static int apply_microcode(const struct microcode_patch *patch) return 0; } -static int scan_equiv_cpu_table( - const void *data, - size_t size_left, - size_t *offset) +static int scan_equiv_cpu_table(const struct container_equiv_table *et) { const struct cpu_signature *sig = &this_cpu(cpu_sig); - const struct mpbhdr *mpbuf; - const struct equiv_cpu_entry *eq; - unsigned int i, nr; - - if ( size_left < (sizeof(*mpbuf) + 4) || - (mpbuf = data + *offset + 4, - size_left - sizeof(*mpbuf) - 4 < mpbuf->len) ) - { - printk(XENLOG_WARNING "microcode: No space for equivalent cpu table\n"); - return -EINVAL; - } - - *offset += mpbuf->len + CONT_HDR_SIZE; /* add header length */ - - if ( mpbuf->type != UCODE_EQUIV_CPU_TABLE_TYPE ) - { - printk(KERN_ERR "microcode: Wrong microcode equivalent cpu table type field\n"); - return -EINVAL; - } - - if ( mpbuf->len == 0 || mpbuf->len % sizeof(*eq) || - (eq = (const void *)mpbuf->data, - nr = mpbuf->len / sizeof(*eq), - eq[nr - 1].installed_cpu) ) - { - printk(KERN_ERR "microcode: Wrong microcode equivalent cpu table length\n"); - return -EINVAL; - } + unsigned int i, nr = et->len / sizeof(et->eq[0]); /* Search the equiv_cpu_table for the current CPU. */ - for ( i = 0; i < nr && eq[i].installed_cpu; ++i ) + for ( i = 0; i < nr && et->eq[i].installed_cpu; ++i ) { - if ( eq[i].installed_cpu != sig->sig ) + if ( et->eq[i].installed_cpu != sig->sig ) continue; if ( !equiv.sig ) /* Cache details on first find. */ { equiv.sig = sig->sig; - equiv.id = eq[i].equiv_cpu; + equiv.id = et->eq[i].equiv_cpu; return 0; } - if ( equiv.sig != sig->sig || equiv.id != eq[i].equiv_cpu ) + if ( equiv.sig != sig->sig || equiv.id != et->eq[i].equiv_cpu ) { /* * This can only occur if two equiv tables have been seen with @@ -327,7 +293,7 @@ static int scan_equiv_cpu_table( */ printk(XENLOG_ERR "microcode: Equiv mismatch: cpu %08x, got %04x, cached %04x\n", - sig->sig, eq[i].equiv_cpu, equiv.id); + sig->sig, et->eq[i].equiv_cpu, equiv.id); return -EINVAL; } @@ -338,101 +304,51 @@ static int scan_equiv_cpu_table( return -ESRCH; } -static int container_fast_forward(const void *data, size_t size_left, size_t *offset) -{ - for ( ; ; ) - { - size_t size; - const uint32_t *header; - - if ( size_left < SECTION_HDR_SIZE ) - return -EINVAL; - - header = data + *offset; - - if ( header[0] == UCODE_MAGIC && - header[1] == UCODE_EQUIV_CPU_TABLE_TYPE ) - break; - - if ( header[0] != UCODE_UCODE_TYPE ) - return -EINVAL; - size = header[1] + SECTION_HDR_SIZE; - if ( size < PATCH_HDR_SIZE || size_left < size ) - return -EINVAL; - - size_left -= size; - *offset += size; - - if ( !size_left ) - return -ENODATA; - } - - return 0; -} - static struct microcode_patch *cpu_request_microcode(const void *buf, size_t size) { const struct microcode_patch *saved = NULL; struct microcode_patch *patch = NULL; - size_t offset = 0, saved_size = 0; + size_t saved_size = 0; int error = 0; - unsigned int cpu = smp_processor_id(); - const struct cpu_signature *sig = &per_cpu(cpu_sig, cpu); - if ( size < 4 || - *(const uint32_t *)buf != UCODE_MAGIC ) + while ( size ) { - printk(KERN_ERR "microcode: Wrong microcode patch file magic\n"); - error = -EINVAL; - goto out; - } - - /* - * Multiple container file support: - * 1. check if this container file has equiv_cpu_id match - * 2. If not, fast-fwd to next container file - */ - while ( offset < size ) - { - error = scan_equiv_cpu_table(buf, size - offset, &offset); - - if ( !error || error != -ESRCH ) - break; + const struct container_equiv_table *et; + bool skip_ucode; - error = container_fast_forward(buf, size - offset, &offset); - if ( error == -ENODATA ) + if ( size < 4 || *(const uint32_t *)buf != UCODE_MAGIC ) { - ASSERT(offset == size); + printk(XENLOG_ERR "microcode: Wrong microcode patch file magic\n"); + error = -EINVAL; break; } - if ( error ) + + /* Move over UCODE_MAGIC. */ + buf += 4; + size -= 4; + + if ( size < sizeof(*et) || + (et = buf)->type != UCODE_EQUIV_CPU_TABLE_TYPE || + size - sizeof(*et) < et->len || + et->len % sizeof(et->eq[0]) ) { - printk(KERN_ERR "microcode: CPU%d incorrect or corrupt container file\n" - "microcode: Failed to update patch level. " - "Current lvl:%#x\n", cpu, sig->rev); + printk(XENLOG_ERR "microcode: Bad equivalent cpu table\n"); + error = -EINVAL; break; } - } - if ( error ) - { - /* - * -ENODATA here means that the blob was parsed fine but no matching - * ucode was found. Don't return it to the caller. - */ - if ( error == -ENODATA ) - error = 0; - - goto out; - } + /* Move over the Equiv table. */ + buf += sizeof(*et) + et->len; + size -= sizeof(*et) + et->len; + + error = scan_equiv_cpu_table(et); + if ( error && error != -ESRCH ) + break; + + /* -ESRCH means no applicable microcode in this container. */ + skip_ucode = error == -ESRCH; + error = 0; - /* - * It's possible the data file has multiple matching ucode, - * lets keep searching till the latest version - */ - buf += offset; - size -= offset; - { while ( size ) { const struct container_microcode *mc; @@ -440,13 +356,16 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, size_t siz if ( size < sizeof(*mc) || (mc = buf)->type != UCODE_UCODE_TYPE || size - sizeof(*mc) < mc->len || - !verify_patch_size(mc->len) ) + (!skip_ucode && !verify_patch_size(mc->len)) ) { printk(XENLOG_ERR "microcode: Bad microcode data\n"); error = -EINVAL; break; } + if ( skip_ucode ) + goto skip; + /* * If the new ucode covers current CPU, compare ucodes and store the * one with higher revision. @@ -459,6 +378,7 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, size_t siz } /* Move over the microcode blob. */ + skip: buf += sizeof(*mc) + mc->len; size -= sizeof(*mc) + mc->len; @@ -478,7 +398,6 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, size_t siz error = -ENOMEM; } - out: if ( error && !patch ) patch = ERR_PTR(error);