From patchwork Mon Mar 23 10:17:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Andrew Cooper X-Patchwork-Id: 11452617 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 C6DC0159A for ; Mon, 23 Mar 2020 10:19:26 +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 A2CF220722 for ; Mon, 23 Mar 2020 10:19:26 +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="IJiJap0V" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A2CF220722 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 1jGK9l-0007jo-01; Mon, 23 Mar 2020 10:18:04 +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 1jGK9k-0007jO-Iq for xen-devel@lists.xenproject.org; Mon, 23 Mar 2020 10:18:04 +0000 X-Inumbo-ID: 917515f1-6cef-11ea-829d-12813bfff9fa Received: from esa5.hc3370-68.iphmx.com (unknown [216.71.155.168]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 917515f1-6cef-11ea-829d-12813bfff9fa; Mon, 23 Mar 2020 10:17:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1584958679; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=1FBUYOW6q9VnSkHwIeoLxYMh8A8QDKI33buuWHabfZM=; b=IJiJap0Ve1y56T4GJGagotI2aN+VZ2zzEW6fu3ebhh+3XmRO31ZT631A TdyHN0dbzq/U2kL96/8MzzSXpWl3sU+29vAbQjBAt0SvzQsXwh7EI2Bz+ OCORcHwdbb4WYo3PM5nArSCraAaNY9/rB8RKF+kP+0c5Q2zcDwR2/Mg0p M=; 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: cUSIDkbqAAfaLr/3qkFqxABdgttBjhonvt4Q/eur4ZmaJ17lCgvRYRZl8YaNsGOQYTkGkSkqJY IM/+IBS3GDo8inCtGj2p1D5YRAjYIgM/lveWBZ2loM5ldjEr6r6V02mFdbMgCmGeO4DAgg98ok L8rpaIiYnveh8C0aWJDPU8MK/uGAF0bQZiR39Pe7pUZbt1KJ2Y1Gu50zU7hzcn/EBVZejOugVy BqihKEIoAdsY5UBUaVgqAc5s8LRsdNzA72QE+q0tXHz9NzY3gxbRWUqe/A0lsOiZ/a7nIH/w+c vUM= X-SBRS: 2.7 X-MesageID: 14788291 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,296,1580792400"; d="scan'208";a="14788291" From: Andrew Cooper To: Xen-devel Date: Mon, 23 Mar 2020 10:17:20 +0000 Message-ID: <20200323101724.15655-4-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 3/7] x86/ucode/intel: Remove gratuitous memory allocations from cpu_request_microcode() 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() needs to scan its container and duplicate one blob, but the get_next_ucode_from_buffer() helper duplicates every blob in turn. Furthermore, the length checking is only safe from overflow in 64bit builds. Delete get_next_ucode_from_buffer() and alter the purpose of the saved variable to simply point somewhere in buf until we're ready to return. This is only a modest reduction in absolute code size (-144), but avoids making memory allocations for every blob in the container. Signed-off-by: Andrew Cooper --- CC: Jan Beulich CC: Wei Liu CC: Roger Pau Monné --- xen/arch/x86/cpu/microcode/intel.c | 69 ++++++++++++++------------------------ 1 file changed, 26 insertions(+), 43 deletions(-) diff --git a/xen/arch/x86/cpu/microcode/intel.c b/xen/arch/x86/cpu/microcode/intel.c index f0beefe1bb..0cceac6255 100644 --- a/xen/arch/x86/cpu/microcode/intel.c +++ b/xen/arch/x86/cpu/microcode/intel.c @@ -321,75 +321,58 @@ static int apply_microcode(const struct microcode_patch *patch) return 0; } -static long get_next_ucode_from_buffer(struct microcode_intel **mc, - const uint8_t *buf, unsigned long size, - unsigned long offset) -{ - struct microcode_header_intel *mc_header; - unsigned long total_size; - - /* No more data */ - if ( offset >= size ) - return 0; - mc_header = (struct microcode_header_intel *)(buf + offset); - total_size = get_totalsize(mc_header); - - if ( (offset + total_size) > size ) - { - printk(KERN_ERR "microcode: error! Bad data in microcode data file\n"); - return -EINVAL; - } - - *mc = xmemdup_bytes(mc_header, total_size); - if ( *mc == NULL ) - return -ENOMEM; - - return offset + total_size; -} - static struct microcode_patch *cpu_request_microcode(const void *buf, size_t size) { - long offset = 0; int error = 0; - struct microcode_intel *mc, *saved = NULL; + const struct microcode_intel *saved = NULL; struct microcode_patch *patch = NULL; - while ( (offset = get_next_ucode_from_buffer(&mc, buf, size, offset)) > 0 ) + while ( size ) { - error = microcode_sanity_check(mc); - if ( error ) + const struct microcode_intel *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? */ + size < (blob_size = /* Insufficient space for patch? */ + get_totalsize(&mc->hdr)) ) { - xfree(mc); + error = -EINVAL; break; } + error = microcode_sanity_check(mc); + if ( error ) + break; + /* * If the new update covers current CPU, compare updates and store the * one with higher revision. */ if ( (microcode_update_match(mc) != MIS_UCODE) && (!saved || (mc->hdr.rev > saved->hdr.rev)) ) - { - xfree(saved); saved = mc; - } - else - xfree(mc); + + buf += blob_size; + size -= blob_size; } - if ( offset < 0 ) - error = offset; if ( saved ) { patch = xmalloc(struct microcode_patch); if ( patch ) - patch->mc_intel = saved; - else { - xfree(saved); - error = -ENOMEM; + patch->mc_intel = xmemdup_bytes(saved, get_totalsize(&saved->hdr)); + if ( !patch->mc_intel ) + { + XFREE(patch); + error = -ENOMEM; + } } + else + error = -ENOMEM; } if ( error && !patch )