From patchwork Mon Mar 23 10:17: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: 11452609 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 DE1926CA for ; Mon, 23 Mar 2020 10:19:07 +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 AE67220409 for ; Mon, 23 Mar 2020 10:19:07 +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="MRHRvNGF" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AE67220409 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 1jGK9O-0007XJ-K0; Mon, 23 Mar 2020 10:17:42 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1jGK9N-0007Ws-Cu for xen-devel@lists.xenproject.org; Mon, 23 Mar 2020 10:17:41 +0000 X-Inumbo-ID: 851d5bf0-6cef-11ea-bec1-bc764e2007e4 Received: from esa4.hc3370-68.iphmx.com (unknown [216.71.155.144]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 851d5bf0-6cef-11ea-bec1-bc764e2007e4; Mon, 23 Mar 2020 10:17:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1584958657; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=oY1vI/otJqmLyA7rCioLLDt00ejjHRZ/yqa6F3MCnfI=; b=MRHRvNGF6mkmgsQMuFbvGBb13vJgppMdp3mumG48Of5U3YvChL3bxU0l 9j7rqMTxf8u6/Dzy2JhS7YXYsyxzPpF3/6rB7f/96ijxtYZvbu0o++1TY cR/TY0Dk30eDMrVYCQTcR0Wu2tzx5vm/abfXX2uUpU+NhoYWJoZV1usl+ 8=; Authentication-Results: esa4.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 (esa4.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=esa4.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="andrew.cooper3@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa4.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=esa4.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 (esa4.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=esa4.hc3370-68.iphmx.com; envelope-from="Andrew.Cooper3@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: T8aB5NzSWaUhgRXZotbC0J50HLLtbzCLOTtBisY27fKZRyy/vTO/Clc+mAstvNNw77gaHbLTvN DJ8BroynwEa0Ghfkorm9ko2BzPmbYc3Dgx5e/waYXaXLNF+KAPFrqTquoux4UKUiWy+HfWJjsE rhNDXbnsbAcpDU+uH4BRFvnGYz3Y+Ymu5XnCs2ZNjoSvVuMIhs6PmqfzcmneHtVJlekapGRhDq I5wAbwqNu7NqgTrHNYyVaJ0ubSxCsA1a/r729RwPPTxaG2SjDoxSLmOVai5kAeP6NeKyY+W69B WUQ= X-SBRS: 2.7 X-MesageID: 15099729 X-Ironport-Server: esa4.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.72,296,1580792400"; d="scan'208";a="15099729" From: Andrew Cooper To: Xen-devel Date: Mon, 23 Mar 2020 10:17:24 +0000 Message-ID: <20200323101724.15655-8-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20200323101724.15655-1-andrew.cooper3@citrix.com> References: <20200323101724.15655-1-andrew.cooper3@citrix.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH 7/7] x86/ucode/intel: Fold structures together 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" Currently, we allocate an 8 byte struct microcode_patch to point at a separately allocated struct microcode_intel. This is wasteful. Fold struct microcode_header_intel and microcode_intel into microcode_patch to simplify the code and remove a level of indirection. The two semantic changes are in free_patch() and cpu_request_microcode() which deal with the memory allocation aspects. Everything else is no functional change. Signed-off-by: Andrew Cooper --- CC: Jan Beulich CC: Wei Liu CC: Roger Pau Monné --- xen/arch/x86/cpu/microcode/intel.c | 103 +++++++++++++------------------------ 1 file changed, 37 insertions(+), 66 deletions(-) diff --git a/xen/arch/x86/cpu/microcode/intel.c b/xen/arch/x86/cpu/microcode/intel.c index 2cccf9c26d..8f4ebbd759 100644 --- a/xen/arch/x86/cpu/microcode/intel.c +++ b/xen/arch/x86/cpu/microcode/intel.c @@ -32,17 +32,12 @@ #define pr_debug(x...) ((void)0) -struct microcode_header_intel { +struct microcode_patch { unsigned int hdrver; unsigned int rev; - union { - struct { - uint16_t year; - uint8_t day; - uint8_t month; - }; - unsigned int date; - }; + uint16_t year; + uint8_t day; + uint8_t month; unsigned int sig; unsigned int cksum; unsigned int ldrver; @@ -57,10 +52,7 @@ struct microcode_header_intel { unsigned int _datasize; unsigned int _totalsize; unsigned int reserved[3]; -}; -struct microcode_intel { - struct microcode_header_intel hdr; uint8_t data[]; }; @@ -76,21 +68,17 @@ struct extended_sigtable { } sigs[]; }; -struct microcode_patch { - struct microcode_intel *mc_intel; -}; - #define PPRO_UCODE_DATASIZE 2000 -#define MC_HEADER_SIZE (sizeof(struct microcode_header_intel)) +#define MC_HEADER_SIZE offsetof(struct microcode_patch, data) -static uint32_t get_datasize(const struct microcode_header_intel *hdr) +static uint32_t get_datasize(const struct microcode_patch *mc) { - return hdr->_datasize ?: PPRO_UCODE_DATASIZE; + return mc->_datasize ?: PPRO_UCODE_DATASIZE; } -static uint32_t get_totalsize(const struct microcode_header_intel *hdr) +static uint32_t get_totalsize(const struct microcode_patch *mc) { - return hdr->_totalsize ?: PPRO_UCODE_DATASIZE + MC_HEADER_SIZE; + return mc->_totalsize ?: PPRO_UCODE_DATASIZE + MC_HEADER_SIZE; } /* @@ -100,10 +88,10 @@ static uint32_t get_totalsize(const struct microcode_header_intel *hdr) * fields, and no extended signature table.) */ static const struct extended_sigtable *get_ext_sigtable( - const struct microcode_intel *mc) + const struct microcode_patch *mc) { - if ( mc->hdr._totalsize > (MC_HEADER_SIZE + mc->hdr._datasize) ) - return (void *)&mc->data[mc->hdr._datasize]; + if ( mc->_totalsize > (MC_HEADER_SIZE + mc->_datasize) ) + return (void *)&mc->data[mc->_datasize]; return NULL; } @@ -158,11 +146,11 @@ static int collect_cpu_info(struct cpu_signature *csig) * header is of a known format, and together with totalsize are within the * bounds of the container. Everything else is unchecked. */ -static int microcode_sanity_check(const struct microcode_intel *mc) +static int microcode_sanity_check(const struct microcode_patch *mc) { const struct extended_sigtable *ext; - unsigned int total_size = get_totalsize(&mc->hdr); - unsigned int data_size = get_datasize(&mc->hdr); + unsigned int total_size = get_totalsize(mc); + unsigned int data_size = get_datasize(mc); unsigned int i, ext_size; uint32_t sum, *ptr; @@ -211,7 +199,7 @@ static int microcode_sanity_check(const struct microcode_intel *mc) * Checksum each indiviudal extended signature as if it had been in the * main header. */ - sum = mc->hdr.sig + mc->hdr.pf + mc->hdr.cksum; + sum = mc->sig + mc->pf + mc->cksum; for ( i = 0; i < ext->count; ++i ) if ( sum != (ext->sigs[i].sig + ext->sigs[i].pf + ext->sigs[i].cksum) ) return -EINVAL; @@ -221,7 +209,7 @@ static int microcode_sanity_check(const struct microcode_intel *mc) /* Check an update against the CPU signature and current update revision */ static enum microcode_match_result microcode_update_match( - const struct microcode_intel *mc) + const struct microcode_patch *mc) { const struct extended_sigtable *ext; unsigned int i; @@ -230,7 +218,7 @@ static enum microcode_match_result microcode_update_match( ASSERT(!microcode_sanity_check(mc)); /* Check the main microcode signature. */ - if ( signature_maches(cpu_sig, mc->hdr.sig, mc->hdr.pf) ) + if ( signature_maches(cpu_sig, mc->sig, mc->pf) ) goto found; /* If there is an extended signature table, check each of them. */ @@ -242,7 +230,7 @@ static enum microcode_match_result microcode_update_match( return MIS_UCODE; found: - return mc->hdr.rev > cpu_sig->rev ? NEW_UCODE : OLD_UCODE; + return mc->rev > cpu_sig->rev ? NEW_UCODE : OLD_UCODE; } static bool match_cpu(const struct microcode_patch *patch) @@ -250,16 +238,12 @@ static bool match_cpu(const struct microcode_patch *patch) if ( !patch ) return false; - return microcode_update_match(patch->mc_intel) == NEW_UCODE; + return microcode_update_match(patch) == NEW_UCODE; } static void free_patch(struct microcode_patch *patch) { - if ( patch ) - { - xfree(patch->mc_intel); - xfree(patch); - } + xfree(patch); } static enum microcode_match_result compare_patch( @@ -269,11 +253,10 @@ static enum microcode_match_result compare_patch( * Both patches to compare are supposed to be applicable to local CPU. * Just compare the revision number. */ - ASSERT(microcode_update_match(old->mc_intel) != MIS_UCODE); - ASSERT(microcode_update_match(new->mc_intel) != MIS_UCODE); + ASSERT(microcode_update_match(old) != MIS_UCODE); + ASSERT(microcode_update_match(new) != MIS_UCODE); - return (new->mc_intel->hdr.rev > old->mc_intel->hdr.rev) ? NEW_UCODE - : OLD_UCODE; + return new->rev > old->rev ? NEW_UCODE : OLD_UCODE; } static int apply_microcode(const struct microcode_patch *patch) @@ -281,7 +264,6 @@ static int apply_microcode(const struct microcode_patch *patch) uint64_t msr_content; unsigned int cpu = smp_processor_id(); struct cpu_signature *sig = &this_cpu(cpu_sig); - const struct microcode_intel *mc_intel; uint32_t rev, old_rev = sig->rev; if ( !patch ) @@ -290,12 +272,10 @@ static int apply_microcode(const struct microcode_patch *patch) if ( !match_cpu(patch) ) return -EINVAL; - mc_intel = patch->mc_intel; - BUG_ON(local_irq_is_enabled()); /* write microcode via MSR 0x79 */ - wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)mc_intel->data); + wrmsrl(MSR_IA32_UCODE_WRITE, (unsigned long)patch->data); wrmsrl(MSR_IA32_UCODE_REV, 0x0ULL); /* As documented in the SDM: Do a CPUID 1 here */ @@ -305,18 +285,17 @@ static int apply_microcode(const struct microcode_patch *patch) rdmsrl(MSR_IA32_UCODE_REV, msr_content); sig->rev = rev = msr_content >> 32; - if ( rev != mc_intel->hdr.rev ) + if ( rev != patch->rev ) { printk(XENLOG_ERR "microcode: CPU%u update rev %#x to %#x failed, result %#x\n", - cpu, old_rev, mc_intel->hdr.rev, rev); + cpu, old_rev, patch->rev, rev); return -EIO; } printk(XENLOG_WARNING "microcode: CPU%u updated from revision %#x to %#x, date = %04x-%02x-%02x\n", - cpu, old_rev, rev, mc_intel->hdr.year, - mc_intel->hdr.month, mc_intel->hdr.day); + cpu, old_rev, rev, patch->year, patch->month, patch->day); return 0; } @@ -325,19 +304,19 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, size_t size) { int error = 0; - const struct microcode_intel *saved = NULL; + const struct microcode_patch *saved = NULL; struct microcode_patch *patch = NULL; while ( size ) { - const struct microcode_intel *mc; + const struct microcode_patch *mc; unsigned int blob_size; if ( size < MC_HEADER_SIZE || /* Insufficient space for header? */ - (mc = buf)->hdr.hdrver != 1 || /* Unrecognised header version? */ - mc->hdr.ldrver != 1 || /* Unrecognised loader version? */ + (mc = buf)->hdrver != 1 || /* Unrecognised header version? */ + mc->ldrver != 1 || /* Unrecognised loader version? */ size < (blob_size = /* Insufficient space for patch? */ - get_totalsize(&mc->hdr)) ) + get_totalsize(mc)) ) { error = -EINVAL; break; @@ -352,7 +331,7 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, * one with higher revision. */ if ( (microcode_update_match(mc) != MIS_UCODE) && - (!saved || (mc->hdr.rev > saved->hdr.rev)) ) + (!saved || (mc->rev > saved->rev)) ) saved = mc; buf += blob_size; @@ -361,17 +340,9 @@ static struct microcode_patch *cpu_request_microcode(const void *buf, if ( saved ) { - patch = xmalloc(struct microcode_patch); - if ( patch ) - { - patch->mc_intel = xmemdup_bytes(saved, get_totalsize(&saved->hdr)); - if ( !patch->mc_intel ) - { - XFREE(patch); - error = -ENOMEM; - } - } - else + patch = xmemdup_bytes(saved, get_totalsize(saved)); + + if ( !patch ) error = -ENOMEM; }