From nobody Mon Feb 9 10:32:22 2026 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 192.237.175.120 is neither permitted nor denied by domain of lists.xenproject.org) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 192.237.175.120 is neither permitted nor denied by domain of lists.xenproject.org) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1568272801; cv=none; d=zoho.com; s=zohoarc; b=XSP5pLaTG7TsQlSQSmdwm0rZxWSOoCwa4BzAgyab1du4xwDDcjGxG8omiGxS+POOs2lnjTEb5LhfJwNUMD5Q9HIz7yX/6x1sOZlhh5+E9ZHDTKbm3AGcjVA36VeAzFc/Iy8Jmq3mlTr+UM8o9Cjh3D8701WqqbqYBu4IQkNhBz8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1568272801; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=Dq02lYH287sB8YQ4tGawsu+9MfmDaiK9IgSm34f3y5Y=; b=cTQjHG656oauDBTr1Uw9DAwftrP5R5k8ylFhoKwKqKFBP8jL9KyViHAgTl/ioNss6r6HUeJw+6KXWgen4JShlQjE/VMoUgw8Fe/oduTgHekhldqU7WI/NNeszKQTbYd33jEYe2mzeVaGI5OOAq0FWBP4x+/QUrUnVmi0kyHqlzQ= ARC-Authentication-Results: i=1; mx.zoho.com; spf=none (zoho.com: 192.237.175.120 is neither permitted nor denied by domain of lists.xenproject.org) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1568272801184988.9618469114384; Thu, 12 Sep 2019 00:20:01 -0700 (PDT) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1i8JNV-0001TH-PO; Thu, 12 Sep 2019 07:18:53 +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 1i8JNU-0001Rk-77 for xen-devel@lists.xenproject.org; Thu, 12 Sep 2019 07:18:52 +0000 Received: from mga01.intel.com (unknown [192.55.52.88]) by us1-amaz-eas2.inumbo.com (Halon) with ESMTPS id 8e10dee4-d52d-11e9-83e3-12813bfff9fa; Thu, 12 Sep 2019 07:18:44 +0000 (UTC) Received: from orsmga006.jf.intel.com ([10.7.209.51]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 12 Sep 2019 00:18:44 -0700 Received: from gao-cwp.sh.intel.com ([10.239.159.26]) by orsmga006.jf.intel.com with ESMTP; 12 Sep 2019 00:18:42 -0700 X-Inumbo-ID: 8e10dee4-d52d-11e9-83e3-12813bfff9fa X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,492,1559545200"; d="scan'208";a="189906239" From: Chao Gao To: xen-devel@lists.xenproject.org Date: Thu, 12 Sep 2019 15:22:18 +0800 Message-Id: <1568272949-1086-6-git-send-email-chao.gao@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1568272949-1086-1-git-send-email-chao.gao@intel.com> References: <1568272949-1086-1-git-send-email-chao.gao@intel.com> Subject: [Xen-devel] [PATCH v10 05/16] microcode: remove struct ucode_cpu_info 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: Sergey Dyasli , Ashok Raj , Wei Liu , Andrew Cooper , Jan Beulich , Chao Gao , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Remove the per-cpu cache field in struct ucode_cpu_info since it has been replaced by a global cache. It would leads to only one field remaining in ucode_cpu_info. Then, this struct is removed and the remaining field (cpu signature) is stored in per-cpu area. The cpu status notifier is also removed. It was used to free the "mc" field to avoid memory leak. Signed-off-by: Chao Gao Reviewed-by: Jan Beulich --- Changes in v9: - rebase and fix conflict Changes in v8: - split microcode_resume_cpu() cleanup to a separate patch. Changes in v6: - remove the whole struct ucode_cpu_info instead of the per-cpu cache in it. --- xen/arch/x86/apic.c | 2 +- xen/arch/x86/microcode.c | 57 +++++++------------------------------= -- xen/arch/x86/microcode_amd.c | 59 +++++++++----------------------------= ---- xen/arch/x86/microcode_intel.c | 28 +++++++------------ xen/arch/x86/spec_ctrl.c | 2 +- xen/include/asm-x86/microcode.h | 12 +-------- 6 files changed, 34 insertions(+), 126 deletions(-) diff --git a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c index ea0d561..6cdb50c 100644 --- a/xen/arch/x86/apic.c +++ b/xen/arch/x86/apic.c @@ -1190,7 +1190,7 @@ static void __init check_deadline_errata(void) else rev =3D (unsigned long)m->driver_data; =20 - if ( this_cpu(ucode_cpu_info).cpu_sig.rev >=3D rev ) + if ( this_cpu(cpu_sig).rev >=3D rev ) return; =20 setup_clear_cpu_cap(X86_FEATURE_TSC_DEADLINE); diff --git a/xen/arch/x86/microcode.c b/xen/arch/x86/microcode.c index 922b94f..d17dbec 100644 --- a/xen/arch/x86/microcode.c +++ b/xen/arch/x86/microcode.c @@ -187,7 +187,7 @@ const struct microcode_ops *microcode_ops; =20 static DEFINE_SPINLOCK(microcode_mutex); =20 -DEFINE_PER_CPU(struct ucode_cpu_info, ucode_cpu_info); +DEFINE_PER_CPU(struct cpu_signature, cpu_sig); =20 struct microcode_info { unsigned int cpu; @@ -196,32 +196,17 @@ struct microcode_info { char buffer[1]; }; =20 -static void __microcode_fini_cpu(unsigned int cpu) -{ - struct ucode_cpu_info *uci =3D &per_cpu(ucode_cpu_info, cpu); - - xfree(uci->mc.mc_valid); - memset(uci, 0, sizeof(*uci)); -} - -static void microcode_fini_cpu(unsigned int cpu) -{ - spin_lock(µcode_mutex); - __microcode_fini_cpu(cpu); - spin_unlock(µcode_mutex); -} - int microcode_resume_cpu(unsigned int cpu) { int err; - struct ucode_cpu_info *uci =3D &per_cpu(ucode_cpu_info, cpu); + struct cpu_signature *sig =3D &per_cpu(cpu_sig, cpu); =20 if ( !microcode_ops ) return 0; =20 spin_lock(µcode_mutex); =20 - err =3D microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig); + err =3D microcode_ops->collect_cpu_info(cpu, sig); if ( likely(!err) ) err =3D microcode_ops->apply_microcode(cpu); spin_unlock(µcode_mutex); @@ -268,16 +253,13 @@ static int microcode_update_cpu(const void *buf, size= _t size) { int err; unsigned int cpu =3D smp_processor_id(); - struct ucode_cpu_info *uci =3D &per_cpu(ucode_cpu_info, cpu); + struct cpu_signature *sig =3D &per_cpu(cpu_sig, cpu); =20 spin_lock(µcode_mutex); =20 - err =3D microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig); + err =3D microcode_ops->collect_cpu_info(cpu, sig); if ( likely(!err) ) err =3D microcode_ops->cpu_request_microcode(cpu, buf, size); - else - __microcode_fini_cpu(cpu); - spin_unlock(µcode_mutex); =20 return err; @@ -364,29 +346,10 @@ static int __init microcode_init(void) } __initcall(microcode_init); =20 -static int microcode_percpu_callback( - struct notifier_block *nfb, unsigned long action, void *hcpu) -{ - unsigned int cpu =3D (unsigned long)hcpu; - - switch ( action ) - { - case CPU_DEAD: - microcode_fini_cpu(cpu); - break; - } - - return NOTIFY_DONE; -} - -static struct notifier_block microcode_percpu_nfb =3D { - .notifier_call =3D microcode_percpu_callback, -}; - int __init early_microcode_update_cpu(bool start_update) { unsigned int cpu =3D smp_processor_id(); - struct ucode_cpu_info *uci =3D &per_cpu(ucode_cpu_info, cpu); + struct cpu_signature *sig =3D &per_cpu(cpu_sig, cpu); int rc =3D 0; void *data =3D NULL; size_t len; @@ -405,7 +368,7 @@ int __init early_microcode_update_cpu(bool start_update) data =3D bootstrap_map(&ucode_mod); } =20 - microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig); + microcode_ops->collect_cpu_info(cpu, sig); =20 if ( data ) { @@ -424,7 +387,7 @@ int __init early_microcode_update_cpu(bool start_update) int __init early_microcode_init(void) { unsigned int cpu =3D smp_processor_id(); - struct ucode_cpu_info *uci =3D &per_cpu(ucode_cpu_info, cpu); + struct cpu_signature *sig =3D &per_cpu(cpu_sig, cpu); int rc; =20 rc =3D microcode_init_intel(); @@ -437,12 +400,10 @@ int __init early_microcode_init(void) =20 if ( microcode_ops ) { - microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig); + microcode_ops->collect_cpu_info(cpu, sig); =20 if ( ucode_mod.mod_end || ucode_blob.size ) rc =3D early_microcode_update_cpu(true); - - register_cpu_notifier(µcode_percpu_nfb); } =20 return rc; diff --git a/xen/arch/x86/microcode_amd.c b/xen/arch/x86/microcode_amd.c index 04b00aa..69c9cfe 100644 --- a/xen/arch/x86/microcode_amd.c +++ b/xen/arch/x86/microcode_amd.c @@ -155,7 +155,7 @@ static bool_t find_equiv_cpu_id(const struct equiv_cpu_= entry *equiv_cpu_table, static enum microcode_match_result microcode_fits( const struct microcode_amd *mc_amd, unsigned int cpu) { - struct ucode_cpu_info *uci =3D &per_cpu(ucode_cpu_info, cpu); + const struct cpu_signature *sig =3D &per_cpu(cpu_sig, cpu); const struct microcode_header_amd *mc_header =3D mc_amd->mpb; const struct equiv_cpu_entry *equiv_cpu_table =3D mc_amd->equiv_cpu_ta= ble; unsigned int current_cpu_id; @@ -178,14 +178,14 @@ static enum microcode_match_result microcode_fits( return MIS_UCODE; } =20 - if ( mc_header->patch_id <=3D uci->cpu_sig.rev ) + if ( mc_header->patch_id <=3D sig->rev ) { pr_debug("microcode: patch is already at required level or greater= .\n"); return OLD_UCODE; } =20 pr_debug("microcode: CPU%d found a matching microcode update with vers= ion %#x (current=3D%#x)\n", - cpu, mc_header->patch_id, uci->cpu_sig.rev); + cpu, mc_header->patch_id, sig->rev); =20 return NEW_UCODE; } @@ -259,9 +259,9 @@ static enum microcode_match_result compare_patch( static int apply_microcode(unsigned int cpu) { unsigned long flags; - struct ucode_cpu_info *uci =3D &per_cpu(ucode_cpu_info, cpu); uint32_t rev; int hw_err; + struct cpu_signature *sig =3D &per_cpu(cpu_sig, cpu); const struct microcode_header_amd *hdr; const struct microcode_patch *patch =3D microcode_get_cache(); =20 @@ -300,9 +300,9 @@ static int apply_microcode(unsigned int cpu) } =20 printk(KERN_WARNING "microcode: CPU%d updated from revision %#x to %#x= \n", - cpu, uci->cpu_sig.rev, hdr->patch_id); + cpu, sig->rev, hdr->patch_id); =20 - uci->cpu_sig.rev =3D rev; + sig->rev =3D rev; =20 return 0; } @@ -448,14 +448,14 @@ static bool_t check_final_patch_levels(unsigned int c= pu) * any of the 'final_levels', then we should not update the microcode * patch on the cpu as system will hang otherwise. */ - struct ucode_cpu_info *uci =3D &per_cpu(ucode_cpu_info, cpu); + const struct cpu_signature *sig =3D &per_cpu(cpu_sig, cpu); unsigned int i; =20 if ( boot_cpu_data.x86 !=3D 0x10 ) return 0; =20 for ( i =3D 0; i < ARRAY_SIZE(final_levels); i++ ) - if ( uci->cpu_sig.rev =3D=3D final_levels[i] ) + if ( sig->rev =3D=3D final_levels[i] ) return 1; =20 return 0; @@ -464,13 +464,12 @@ static bool_t check_final_patch_levels(unsigned int c= pu) static int cpu_request_microcode(unsigned int cpu, const void *buf, size_t bufsize) { - struct microcode_amd *mc_amd, *mc_old; + struct microcode_amd *mc_amd; size_t offset =3D 0; - size_t last_offset, applied_offset =3D 0; - int error =3D 0, save_error =3D 1; - struct ucode_cpu_info *uci =3D &per_cpu(ucode_cpu_info, cpu); + int error =3D 0; unsigned int current_cpu_id; unsigned int equiv_cpu_id; + const struct cpu_signature *sig =3D &per_cpu(cpu_sig, cpu); =20 /* We should bind the task to the CPU */ BUG_ON(cpu !=3D raw_smp_processor_id()); @@ -539,7 +538,7 @@ static int cpu_request_microcode(unsigned int cpu, cons= t void *buf, { printk(KERN_ERR "microcode: CPU%d incorrect or corrupt contain= er file\n" "microcode: Failed to update patch level. " - "Current lvl:%#x\n", cpu, uci->cpu_sig.rev); + "Current lvl:%#x\n", cpu, sig->rev); break; } } @@ -551,15 +550,10 @@ static int cpu_request_microcode(unsigned int cpu, co= nst void *buf, goto out; } =20 - mc_old =3D uci->mc.mc_amd; - /* implicitely validates uci->mc.mc_valid */ - uci->mc.mc_amd =3D mc_amd; - /* * It's possible the data file has multiple matching ucode, * lets keep searching till the latest version */ - last_offset =3D offset; while ( (error =3D get_ucode_from_buffer_amd(mc_amd, buf, bufsize, &offset)) =3D=3D 0 ) { @@ -582,11 +576,8 @@ static int cpu_request_microcode(unsigned int cpu, con= st void *buf, error =3D apply_microcode(cpu); if ( error ) break; - applied_offset =3D last_offset; } =20 - last_offset =3D offset; - if ( offset >=3D bufsize ) break; =20 @@ -614,31 +605,7 @@ static int cpu_request_microcode(unsigned int cpu, con= st void *buf, *(const uint32_t *)(buf + offset) =3D=3D UCODE_MAGIC ) break; } - - /* On success keep the microcode patch for - * re-apply on resume. - */ - if ( applied_offset ) - { - save_error =3D get_ucode_from_buffer_amd( - mc_amd, buf, bufsize, &applied_offset); - - if ( save_error ) - error =3D save_error; - } - - if ( save_error ) - { - uci->mc.mc_amd =3D mc_old; - mc_old =3D mc_amd; - } - - if ( mc_old ) - { - xfree(mc_old->mpb); - xfree(mc_old->equiv_cpu_table); - xfree(mc_old); - } + free_patch(mc_amd); =20 out: #if CONFIG_HVM diff --git a/xen/arch/x86/microcode_intel.c b/xen/arch/x86/microcode_intel.c index 97f759e..f63e4bd 100644 --- a/xen/arch/x86/microcode_intel.c +++ b/xen/arch/x86/microcode_intel.c @@ -231,10 +231,10 @@ static enum microcode_match_result microcode_update_m= atch( const struct extended_sigtable *ext_header; const struct extended_signature *ext_sig; unsigned int i; - struct ucode_cpu_info *uci =3D &per_cpu(ucode_cpu_info, cpu); - unsigned int sig =3D uci->cpu_sig.sig; - unsigned int pf =3D uci->cpu_sig.pf; - unsigned int rev =3D uci->cpu_sig.rev; + struct cpu_signature *cpu_sig =3D &per_cpu(cpu_sig, cpu); + unsigned int sig =3D cpu_sig->sig; + unsigned int pf =3D cpu_sig->pf; + unsigned int rev =3D cpu_sig->rev; unsigned long data_size =3D get_datasize(mc_header); const void *end =3D (const void *)mc_header + get_totalsize(mc_header); =20 @@ -297,7 +297,6 @@ static enum microcode_match_result compare_patch( */ static int get_matching_microcode(const void *mc, unsigned int cpu) { - struct ucode_cpu_info *uci =3D &per_cpu(ucode_cpu_info, cpu); const struct microcode_header_intel *mc_header =3D mc; unsigned long total_size =3D get_totalsize(mc_header); void *new_mc =3D xmalloc_bytes(total_size); @@ -323,17 +322,8 @@ static int get_matching_microcode(const void *mc, unsi= gned int cpu) =20 pr_debug("microcode: CPU%d found a matching microcode update with" " version %#x (current=3D%#x)\n", - cpu, mc_header->rev, uci->cpu_sig.rev); - new_mc =3D xmalloc_bytes(total_size); - if ( new_mc =3D=3D NULL ) - { - printk(KERN_ERR "microcode: error! Can not allocate memory\n"); - return -ENOMEM; - } + cpu, mc_header->rev, per_cpu(cpu_sig, cpu).rev); =20 - memcpy(new_mc, mc, total_size); - xfree(uci->mc.mc_intel); - uci->mc.mc_intel =3D new_mc; return 1; } =20 @@ -343,7 +333,7 @@ static int apply_microcode(unsigned int cpu) uint64_t msr_content; unsigned int val[2]; unsigned int cpu_num =3D raw_smp_processor_id(); - struct ucode_cpu_info *uci =3D &per_cpu(ucode_cpu_info, cpu_num); + struct cpu_signature *sig =3D &per_cpu(cpu_sig, cpu); const struct microcode_intel *mc_intel; const struct microcode_patch *patch =3D microcode_get_cache(); =20 @@ -377,14 +367,14 @@ static int apply_microcode(unsigned int cpu) { printk(KERN_ERR "microcode: CPU%d update from revision " "%#x to %#x failed. Resulting revision is %#x.\n", cpu_num, - uci->cpu_sig.rev, mc_intel->hdr.rev, val[1]); + sig->rev, mc_intel->hdr.rev, val[1]); return -EIO; } printk(KERN_INFO "microcode: CPU%d updated from revision " "%#x to %#x, date =3D %04x-%02x-%02x \n", - cpu_num, uci->cpu_sig.rev, val[1], mc_intel->hdr.year, + cpu_num, sig->rev, val[1], mc_intel->hdr.year, mc_intel->hdr.month, mc_intel->hdr.day); - uci->cpu_sig.rev =3D val[1]; + sig->rev =3D val[1]; =20 return 0; } diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c index 468a847..4761be8 100644 --- a/xen/arch/x86/spec_ctrl.c +++ b/xen/arch/x86/spec_ctrl.c @@ -438,7 +438,7 @@ static bool __init check_smt_enabled(void) /* Calculate whether Retpoline is known-safe on this CPU. */ static bool __init retpoline_safe(uint64_t caps) { - unsigned int ucode_rev =3D this_cpu(ucode_cpu_info).cpu_sig.rev; + unsigned int ucode_rev =3D this_cpu(cpu_sig).rev; =20 if ( boot_cpu_data.x86_vendor & (X86_VENDOR_AMD | X86_VENDOR_HYGON) ) return true; diff --git a/xen/include/asm-x86/microcode.h b/xen/include/asm-x86/microcod= e.h index da0b156..3f4c4be 100644 --- a/xen/include/asm-x86/microcode.h +++ b/xen/include/asm-x86/microcode.h @@ -10,7 +10,6 @@ enum microcode_match_result { }; =20 struct cpu_signature; -struct ucode_cpu_info; =20 struct microcode_patch { union { @@ -38,16 +37,7 @@ struct cpu_signature { unsigned int rev; }; =20 -struct ucode_cpu_info { - struct cpu_signature cpu_sig; - union { - struct microcode_intel *mc_intel; - struct microcode_amd *mc_amd; - void *mc_valid; - } mc; -}; - -DECLARE_PER_CPU(struct ucode_cpu_info, ucode_cpu_info); +DECLARE_PER_CPU(struct cpu_signature, cpu_sig); extern const struct microcode_ops *microcode_ops; =20 const struct microcode_patch *microcode_get_cache(void); --=20 1.8.3.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel