From: Chao Gao <chao.gao@intel.com> To: xen-devel@lists.xenproject.org Cc: "Sergey Dyasli" <sergey.dyasli@citrix.com>, "Ashok Raj" <ashok.raj@intel.com>, "Wei Liu" <wl@xen.org>, "Andrew Cooper" <andrew.cooper3@citrix.com>, "Jan Beulich" <jbeulich@suse.com>, "Chao Gao" <chao.gao@intel.com>, "Roger Pau Monné" <roger.pau@citrix.com> Subject: [PATCH v7 04/10] microcode: remove struct ucode_cpu_info Date: Mon, 27 May 2019 16:31:25 +0800 [thread overview] Message-ID: <1558945891-3015-5-git-send-email-chao.gao@intel.com> (raw) In-Reply-To: <1558945891-3015-1-git-send-email-chao.gao@intel.com> We can 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. Also remove 'microcode_resume_match' from microcode_ops because the check is done in find_patch(). The cpu status notifier is also removed. It was used to free the "mc" field to avoid memory leak. Signed-off-by: Chao Gao <chao.gao@intel.com> --- 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 | 91 +++--------------------------------- xen/arch/x86/microcode_amd.c | 100 +++++----------------------------------- xen/arch/x86/microcode_intel.c | 33 ++++--------- xen/arch/x86/spec_ctrl.c | 2 +- xen/include/asm-x86/microcode.h | 13 +----- 6 files changed, 30 insertions(+), 211 deletions(-) diff --git a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c index fafc0bd..d216455 100644 --- a/xen/arch/x86/apic.c +++ b/xen/arch/x86/apic.c @@ -1188,7 +1188,7 @@ static void __init check_deadline_errata(void) else rev = (unsigned long)m->driver_data; - if ( this_cpu(ucode_cpu_info).cpu_sig.rev >= rev ) + if ( this_cpu(cpu_sig).rev >= rev ) return; setup_clear_cpu_cap(X86_FEATURE_TSC_DEADLINE); diff --git a/xen/arch/x86/microcode.c b/xen/arch/x86/microcode.c index cff86a9..0c01dfa 100644 --- a/xen/arch/x86/microcode.c +++ b/xen/arch/x86/microcode.c @@ -187,7 +187,7 @@ const struct microcode_ops *microcode_ops; static DEFINE_SPINLOCK(microcode_mutex); -DEFINE_PER_CPU(struct ucode_cpu_info, ucode_cpu_info); +DEFINE_PER_CPU(struct cpu_signature, cpu_sig); struct microcode_info { unsigned int cpu; @@ -196,70 +196,19 @@ struct microcode_info { char buffer[1]; }; -static void __microcode_fini_cpu(unsigned int cpu) -{ - struct ucode_cpu_info *uci = &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 = &per_cpu(ucode_cpu_info, cpu); - struct cpu_signature nsig; - unsigned int cpu2; + struct cpu_signature *sig = &per_cpu(cpu_sig, cpu); if ( !microcode_ops ) return 0; spin_lock(µcode_mutex); - err = microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig); - if ( err ) - { - __microcode_fini_cpu(cpu); - spin_unlock(µcode_mutex); - return err; - } - - if ( uci->mc.mc_valid ) - { - err = microcode_ops->microcode_resume_match(cpu, uci->mc.mc_valid); - if ( err >= 0 ) - { - if ( err ) - err = microcode_ops->apply_microcode(cpu); - spin_unlock(µcode_mutex); - return err; - } - } - - nsig = uci->cpu_sig; - __microcode_fini_cpu(cpu); - uci->cpu_sig = nsig; - - err = -EIO; - for_each_online_cpu ( cpu2 ) - { - uci = &per_cpu(ucode_cpu_info, cpu2); - if ( uci->mc.mc_valid && - microcode_ops->microcode_resume_match(cpu, uci->mc.mc_valid) > 0 ) - { - err = microcode_ops->apply_microcode(cpu); - break; - } - } - - __microcode_fini_cpu(cpu); + err = microcode_ops->collect_cpu_info(cpu, sig); + if ( likely(!err) ) + err = microcode_ops->apply_microcode(cpu); spin_unlock(µcode_mutex); return err; @@ -302,16 +251,13 @@ static int microcode_update_cpu(const void *buf, size_t size) { int err; unsigned int cpu = smp_processor_id(); - struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu); + struct cpu_signature *sig = &per_cpu(cpu_sig, cpu); spin_lock(µcode_mutex); - err = microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig); + err = microcode_ops->collect_cpu_info(cpu, sig); if ( likely(!err) ) err = microcode_ops->cpu_request_microcode(cpu, buf, size); - else - __microcode_fini_cpu(cpu); - spin_unlock(µcode_mutex); return err; @@ -398,25 +344,6 @@ static int __init microcode_init(void) } __initcall(microcode_init); -static int microcode_percpu_callback( - struct notifier_block *nfb, unsigned long action, void *hcpu) -{ - unsigned int cpu = (unsigned long)hcpu; - - switch ( action ) - { - case CPU_DEAD: - microcode_fini_cpu(cpu); - break; - } - - return NOTIFY_DONE; -} - -static struct notifier_block microcode_percpu_nfb = { - .notifier_call = microcode_percpu_callback, -}; - int __init early_microcode_update_cpu(bool start_update) { int rc = 0; @@ -460,12 +387,8 @@ int __init early_microcode_init(void) return rc; if ( microcode_ops ) - { if ( ucode_mod.mod_end || ucode_blob.size ) rc = early_microcode_update_cpu(true); - register_cpu_notifier(µcode_percpu_nfb); - } - return rc; } diff --git a/xen/arch/x86/microcode_amd.c b/xen/arch/x86/microcode_amd.c index 1f05899..93af2c9 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 bool_t microcode_fits(const struct microcode_amd *mc_amd, unsigned int cpu) { - struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu); + 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; @@ -178,14 +178,14 @@ static bool_t microcode_fits(const struct microcode_amd *mc_amd, return 0; } - if ( mc_header->patch_id <= uci->cpu_sig.rev ) + if ( mc_header->patch_id <= sig->rev ) { pr_debug("microcode: patch is already at required level or greater.\n"); return 0; } pr_debug("microcode: CPU%d found a matching microcode update with version %#x (current=%#x)\n", - cpu, mc_header->patch_id, uci->cpu_sig.rev); + cpu, mc_header->patch_id, sig->rev); return 1; } @@ -256,9 +256,9 @@ static enum microcode_match_result compare_patch( static int apply_microcode(unsigned int cpu) { unsigned long flags; - struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu); uint32_t rev; int hw_err; + struct cpu_signature *sig = &per_cpu(cpu_sig, cpu); const struct microcode_header_amd *hdr; const struct microcode_patch *patch = microcode_get_cache(); @@ -294,9 +294,9 @@ static int apply_microcode(unsigned int cpu) } 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); - uci->cpu_sig.rev = rev; + sig->rev = rev; return 0; } @@ -442,14 +442,14 @@ static bool_t check_final_patch_levels(unsigned int cpu) * 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 = &per_cpu(ucode_cpu_info, cpu); + 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 ( uci->cpu_sig.rev == final_levels[i] ) + if ( sig->rev == final_levels[i] ) return 1; return 0; @@ -458,13 +458,12 @@ static bool_t check_final_patch_levels(unsigned int cpu) 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 = 0; - size_t last_offset, applied_offset = 0; - int error = 0, save_error = 1; - struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu); + int error = 0; unsigned int current_cpu_id; unsigned int equiv_cpu_id; + const struct cpu_signature *sig = &per_cpu(cpu_sig, cpu); /* We should bind the task to the CPU */ BUG_ON(cpu != raw_smp_processor_id()); @@ -533,7 +532,7 @@ static int cpu_request_microcode(unsigned int cpu, const void *buf, { printk(KERN_ERR "microcode: CPU%d incorrect or corrupt container 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; } } @@ -544,17 +543,12 @@ static int cpu_request_microcode(unsigned int cpu, const void *buf, goto out; } - mc_old = uci->mc.mc_amd; - /* implicitely validates uci->mc.mc_valid */ - uci->mc.mc_amd = mc_amd; - /* * It's possible the data file has multiple matching ucode, * lets keep searching till the latest version */ mc_amd->mpb = NULL; mc_amd->mpb_size = 0; - last_offset = offset; while ( (error = get_ucode_from_buffer_amd(mc_amd, buf, bufsize, &offset)) == 0 ) { @@ -576,11 +570,8 @@ static int cpu_request_microcode(unsigned int cpu, const void *buf, error = apply_microcode(cpu); if ( error ) break; - applied_offset = last_offset; } - last_offset = offset; - if ( offset >= bufsize ) break; @@ -609,26 +600,6 @@ static int cpu_request_microcode(unsigned int cpu, const void *buf, break; } - /* On success keep the microcode patch for - * re-apply on resume. - */ - if ( applied_offset ) - { - save_error = get_ucode_from_buffer_amd( - mc_amd, buf, bufsize, &applied_offset); - - if ( save_error ) - error = save_error; - } - - if ( save_error ) - { - xfree(mc_amd); - uci->mc.mc_amd = mc_old; - } - else - xfree(mc_old); - out: #if CONFIG_HVM svm_host_osvw_init(); @@ -643,52 +614,6 @@ static int cpu_request_microcode(unsigned int cpu, const void *buf, return error; } -static int microcode_resume_match(unsigned int cpu, const void *mc) -{ - struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu); - struct microcode_amd *mc_amd = uci->mc.mc_amd; - const struct microcode_amd *src = mc; - - if ( !microcode_fits(src, cpu) ) - return 0; - - if ( src != mc_amd ) - { - if ( mc_amd ) - { - xfree(mc_amd->equiv_cpu_table); - xfree(mc_amd->mpb); - xfree(mc_amd); - } - - mc_amd = xmalloc(struct microcode_amd); - uci->mc.mc_amd = mc_amd; - if ( !mc_amd ) - return -ENOMEM; - mc_amd->equiv_cpu_table = xmalloc_bytes(src->equiv_cpu_table_size); - if ( !mc_amd->equiv_cpu_table ) - goto err1; - mc_amd->mpb = xmalloc_bytes(src->mpb_size); - if ( !mc_amd->mpb ) - goto err2; - - mc_amd->equiv_cpu_table_size = src->equiv_cpu_table_size; - mc_amd->mpb_size = src->mpb_size; - memcpy(mc_amd->mpb, src->mpb, src->mpb_size); - memcpy(mc_amd->equiv_cpu_table, src->equiv_cpu_table, - src->equiv_cpu_table_size); - } - - return 1; - -err2: - xfree(mc_amd->equiv_cpu_table); -err1: - xfree(mc_amd); - uci->mc.mc_amd = NULL; - return -ENOMEM; -} - static int start_update(void) { #if CONFIG_HVM @@ -708,7 +633,6 @@ static int start_update(void) } static const struct microcode_ops microcode_amd_ops = { - .microcode_resume_match = microcode_resume_match, .cpu_request_microcode = cpu_request_microcode, .collect_cpu_info = collect_cpu_info, .apply_microcode = apply_microcode, diff --git a/xen/arch/x86/microcode_intel.c b/xen/arch/x86/microcode_intel.c index d3405a0..bf6497f 100644 --- a/xen/arch/x86/microcode_intel.c +++ b/xen/arch/x86/microcode_intel.c @@ -250,13 +250,13 @@ static int microcode_sanity_check(void *mc) static bool match_cpu(const struct microcode_patch *patch) { - const struct ucode_cpu_info *uci = &this_cpu(ucode_cpu_info); + const struct cpu_signature *sig = &this_cpu(cpu_sig); if ( !patch ) return false; - return microcode_update_match(&patch->mc_intel->hdr, uci->cpu_sig.sig, - uci->cpu_sig.pf, uci->cpu_sig.rev) == NEW_UCODE; + return microcode_update_match(&patch->mc_intel->hdr, + sig->sig, sig->pf, sig->rev) == NEW_UCODE; } static void free_patch(struct microcode_patch *patch) @@ -281,7 +281,6 @@ static enum microcode_match_result compare_patch( */ static int get_matching_microcode(const void *mc, unsigned int cpu) { - struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu); const struct microcode_header_intel *mc_header = mc; unsigned long total_size = get_totalsize(mc_header); void *new_mc = xmalloc_bytes(total_size); @@ -308,17 +307,7 @@ static int get_matching_microcode(const void *mc, unsigned int cpu) pr_debug("microcode: CPU%d found a matching microcode update with" " version %#x (current=%#x)\n", - cpu, mc_header->rev, uci->cpu_sig.rev); - new_mc = xmalloc_bytes(total_size); - if ( new_mc == NULL ) - { - printk(KERN_ERR "microcode: error! Can not allocate memory\n"); - return -ENOMEM; - } - - memcpy(new_mc, mc, total_size); - xfree(uci->mc.mc_intel); - uci->mc.mc_intel = new_mc; + cpu, mc_header->rev, this_cpu(cpu_sig).rev); return 1; } @@ -329,7 +318,7 @@ static int apply_microcode(unsigned int cpu) uint64_t msr_content; unsigned int val[2]; unsigned int cpu_num = raw_smp_processor_id(); - struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu_num); + struct cpu_signature *sig = &per_cpu(cpu_sig, cpu); const struct microcode_intel *mc_intel; const struct microcode_patch *patch = microcode_get_cache(); @@ -360,16 +349,16 @@ 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 = %04x-%02x-%02x \n", - cpu_num, uci->cpu_sig.rev, val[1], + cpu_num, sig->rev, val[1], mc_intel->hdr.year, mc_intel->hdr.month, mc_intel->hdr.day); - uci->cpu_sig.rev = val[1]; + sig->rev = val[1]; return 0; } @@ -440,13 +429,7 @@ static int cpu_request_microcode(unsigned int cpu, const void *buf, return error; } -static int microcode_resume_match(unsigned int cpu, const void *mc) -{ - return get_matching_microcode(mc, cpu); -} - static const struct microcode_ops microcode_intel_ops = { - .microcode_resume_match = microcode_resume_match, .cpu_request_microcode = cpu_request_microcode, .collect_cpu_info = collect_cpu_info, .apply_microcode = apply_microcode, diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c index 5d98cac..43128c3 100644 --- a/xen/arch/x86/spec_ctrl.c +++ b/xen/arch/x86/spec_ctrl.c @@ -436,7 +436,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 = this_cpu(ucode_cpu_info).cpu_sig.rev; + unsigned int ucode_rev = this_cpu(cpu_sig).rev; if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD ) return true; diff --git a/xen/include/asm-x86/microcode.h b/xen/include/asm-x86/microcode.h index 6541c58..f2ac509 100644 --- a/xen/include/asm-x86/microcode.h +++ b/xen/include/asm-x86/microcode.h @@ -10,7 +10,6 @@ enum microcode_match_result { }; struct cpu_signature; -struct ucode_cpu_info; struct microcode_patch { union { @@ -20,7 +19,6 @@ struct microcode_patch { }; struct microcode_ops { - int (*microcode_resume_match)(unsigned int cpu, const void *mc); int (*cpu_request_microcode)(unsigned int cpu, const void *buf, size_t size); int (*collect_cpu_info)(unsigned int cpu, struct cpu_signature *csig); @@ -39,16 +37,7 @@ struct cpu_signature { unsigned int rev; }; -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; const struct microcode_patch *microcode_get_cache(void); -- 1.8.3.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
WARNING: multiple messages have this Message-ID (diff)
From: Chao Gao <chao.gao@intel.com> To: xen-devel@lists.xenproject.org Cc: "Sergey Dyasli" <sergey.dyasli@citrix.com>, "Ashok Raj" <ashok.raj@intel.com>, "Wei Liu" <wl@xen.org>, "Andrew Cooper" <andrew.cooper3@citrix.com>, "Jan Beulich" <jbeulich@suse.com>, "Chao Gao" <chao.gao@intel.com>, "Roger Pau Monné" <roger.pau@citrix.com> Subject: [Xen-devel] [PATCH v7 04/10] microcode: remove struct ucode_cpu_info Date: Mon, 27 May 2019 16:31:25 +0800 [thread overview] Message-ID: <1558945891-3015-5-git-send-email-chao.gao@intel.com> (raw) Message-ID: <20190527083125.lITO7KgPmzHzttE-DDeEhdCZkB0bhPBKhC_bip_NA0w@z> (raw) In-Reply-To: <1558945891-3015-1-git-send-email-chao.gao@intel.com> We can 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. Also remove 'microcode_resume_match' from microcode_ops because the check is done in find_patch(). The cpu status notifier is also removed. It was used to free the "mc" field to avoid memory leak. Signed-off-by: Chao Gao <chao.gao@intel.com> --- 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 | 91 +++--------------------------------- xen/arch/x86/microcode_amd.c | 100 +++++----------------------------------- xen/arch/x86/microcode_intel.c | 33 ++++--------- xen/arch/x86/spec_ctrl.c | 2 +- xen/include/asm-x86/microcode.h | 13 +----- 6 files changed, 30 insertions(+), 211 deletions(-) diff --git a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c index fafc0bd..d216455 100644 --- a/xen/arch/x86/apic.c +++ b/xen/arch/x86/apic.c @@ -1188,7 +1188,7 @@ static void __init check_deadline_errata(void) else rev = (unsigned long)m->driver_data; - if ( this_cpu(ucode_cpu_info).cpu_sig.rev >= rev ) + if ( this_cpu(cpu_sig).rev >= rev ) return; setup_clear_cpu_cap(X86_FEATURE_TSC_DEADLINE); diff --git a/xen/arch/x86/microcode.c b/xen/arch/x86/microcode.c index cff86a9..0c01dfa 100644 --- a/xen/arch/x86/microcode.c +++ b/xen/arch/x86/microcode.c @@ -187,7 +187,7 @@ const struct microcode_ops *microcode_ops; static DEFINE_SPINLOCK(microcode_mutex); -DEFINE_PER_CPU(struct ucode_cpu_info, ucode_cpu_info); +DEFINE_PER_CPU(struct cpu_signature, cpu_sig); struct microcode_info { unsigned int cpu; @@ -196,70 +196,19 @@ struct microcode_info { char buffer[1]; }; -static void __microcode_fini_cpu(unsigned int cpu) -{ - struct ucode_cpu_info *uci = &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 = &per_cpu(ucode_cpu_info, cpu); - struct cpu_signature nsig; - unsigned int cpu2; + struct cpu_signature *sig = &per_cpu(cpu_sig, cpu); if ( !microcode_ops ) return 0; spin_lock(µcode_mutex); - err = microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig); - if ( err ) - { - __microcode_fini_cpu(cpu); - spin_unlock(µcode_mutex); - return err; - } - - if ( uci->mc.mc_valid ) - { - err = microcode_ops->microcode_resume_match(cpu, uci->mc.mc_valid); - if ( err >= 0 ) - { - if ( err ) - err = microcode_ops->apply_microcode(cpu); - spin_unlock(µcode_mutex); - return err; - } - } - - nsig = uci->cpu_sig; - __microcode_fini_cpu(cpu); - uci->cpu_sig = nsig; - - err = -EIO; - for_each_online_cpu ( cpu2 ) - { - uci = &per_cpu(ucode_cpu_info, cpu2); - if ( uci->mc.mc_valid && - microcode_ops->microcode_resume_match(cpu, uci->mc.mc_valid) > 0 ) - { - err = microcode_ops->apply_microcode(cpu); - break; - } - } - - __microcode_fini_cpu(cpu); + err = microcode_ops->collect_cpu_info(cpu, sig); + if ( likely(!err) ) + err = microcode_ops->apply_microcode(cpu); spin_unlock(µcode_mutex); return err; @@ -302,16 +251,13 @@ static int microcode_update_cpu(const void *buf, size_t size) { int err; unsigned int cpu = smp_processor_id(); - struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu); + struct cpu_signature *sig = &per_cpu(cpu_sig, cpu); spin_lock(µcode_mutex); - err = microcode_ops->collect_cpu_info(cpu, &uci->cpu_sig); + err = microcode_ops->collect_cpu_info(cpu, sig); if ( likely(!err) ) err = microcode_ops->cpu_request_microcode(cpu, buf, size); - else - __microcode_fini_cpu(cpu); - spin_unlock(µcode_mutex); return err; @@ -398,25 +344,6 @@ static int __init microcode_init(void) } __initcall(microcode_init); -static int microcode_percpu_callback( - struct notifier_block *nfb, unsigned long action, void *hcpu) -{ - unsigned int cpu = (unsigned long)hcpu; - - switch ( action ) - { - case CPU_DEAD: - microcode_fini_cpu(cpu); - break; - } - - return NOTIFY_DONE; -} - -static struct notifier_block microcode_percpu_nfb = { - .notifier_call = microcode_percpu_callback, -}; - int __init early_microcode_update_cpu(bool start_update) { int rc = 0; @@ -460,12 +387,8 @@ int __init early_microcode_init(void) return rc; if ( microcode_ops ) - { if ( ucode_mod.mod_end || ucode_blob.size ) rc = early_microcode_update_cpu(true); - register_cpu_notifier(µcode_percpu_nfb); - } - return rc; } diff --git a/xen/arch/x86/microcode_amd.c b/xen/arch/x86/microcode_amd.c index 1f05899..93af2c9 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 bool_t microcode_fits(const struct microcode_amd *mc_amd, unsigned int cpu) { - struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu); + 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; @@ -178,14 +178,14 @@ static bool_t microcode_fits(const struct microcode_amd *mc_amd, return 0; } - if ( mc_header->patch_id <= uci->cpu_sig.rev ) + if ( mc_header->patch_id <= sig->rev ) { pr_debug("microcode: patch is already at required level or greater.\n"); return 0; } pr_debug("microcode: CPU%d found a matching microcode update with version %#x (current=%#x)\n", - cpu, mc_header->patch_id, uci->cpu_sig.rev); + cpu, mc_header->patch_id, sig->rev); return 1; } @@ -256,9 +256,9 @@ static enum microcode_match_result compare_patch( static int apply_microcode(unsigned int cpu) { unsigned long flags; - struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu); uint32_t rev; int hw_err; + struct cpu_signature *sig = &per_cpu(cpu_sig, cpu); const struct microcode_header_amd *hdr; const struct microcode_patch *patch = microcode_get_cache(); @@ -294,9 +294,9 @@ static int apply_microcode(unsigned int cpu) } 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); - uci->cpu_sig.rev = rev; + sig->rev = rev; return 0; } @@ -442,14 +442,14 @@ static bool_t check_final_patch_levels(unsigned int cpu) * 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 = &per_cpu(ucode_cpu_info, cpu); + 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 ( uci->cpu_sig.rev == final_levels[i] ) + if ( sig->rev == final_levels[i] ) return 1; return 0; @@ -458,13 +458,12 @@ static bool_t check_final_patch_levels(unsigned int cpu) 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 = 0; - size_t last_offset, applied_offset = 0; - int error = 0, save_error = 1; - struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu); + int error = 0; unsigned int current_cpu_id; unsigned int equiv_cpu_id; + const struct cpu_signature *sig = &per_cpu(cpu_sig, cpu); /* We should bind the task to the CPU */ BUG_ON(cpu != raw_smp_processor_id()); @@ -533,7 +532,7 @@ static int cpu_request_microcode(unsigned int cpu, const void *buf, { printk(KERN_ERR "microcode: CPU%d incorrect or corrupt container 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; } } @@ -544,17 +543,12 @@ static int cpu_request_microcode(unsigned int cpu, const void *buf, goto out; } - mc_old = uci->mc.mc_amd; - /* implicitely validates uci->mc.mc_valid */ - uci->mc.mc_amd = mc_amd; - /* * It's possible the data file has multiple matching ucode, * lets keep searching till the latest version */ mc_amd->mpb = NULL; mc_amd->mpb_size = 0; - last_offset = offset; while ( (error = get_ucode_from_buffer_amd(mc_amd, buf, bufsize, &offset)) == 0 ) { @@ -576,11 +570,8 @@ static int cpu_request_microcode(unsigned int cpu, const void *buf, error = apply_microcode(cpu); if ( error ) break; - applied_offset = last_offset; } - last_offset = offset; - if ( offset >= bufsize ) break; @@ -609,26 +600,6 @@ static int cpu_request_microcode(unsigned int cpu, const void *buf, break; } - /* On success keep the microcode patch for - * re-apply on resume. - */ - if ( applied_offset ) - { - save_error = get_ucode_from_buffer_amd( - mc_amd, buf, bufsize, &applied_offset); - - if ( save_error ) - error = save_error; - } - - if ( save_error ) - { - xfree(mc_amd); - uci->mc.mc_amd = mc_old; - } - else - xfree(mc_old); - out: #if CONFIG_HVM svm_host_osvw_init(); @@ -643,52 +614,6 @@ static int cpu_request_microcode(unsigned int cpu, const void *buf, return error; } -static int microcode_resume_match(unsigned int cpu, const void *mc) -{ - struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu); - struct microcode_amd *mc_amd = uci->mc.mc_amd; - const struct microcode_amd *src = mc; - - if ( !microcode_fits(src, cpu) ) - return 0; - - if ( src != mc_amd ) - { - if ( mc_amd ) - { - xfree(mc_amd->equiv_cpu_table); - xfree(mc_amd->mpb); - xfree(mc_amd); - } - - mc_amd = xmalloc(struct microcode_amd); - uci->mc.mc_amd = mc_amd; - if ( !mc_amd ) - return -ENOMEM; - mc_amd->equiv_cpu_table = xmalloc_bytes(src->equiv_cpu_table_size); - if ( !mc_amd->equiv_cpu_table ) - goto err1; - mc_amd->mpb = xmalloc_bytes(src->mpb_size); - if ( !mc_amd->mpb ) - goto err2; - - mc_amd->equiv_cpu_table_size = src->equiv_cpu_table_size; - mc_amd->mpb_size = src->mpb_size; - memcpy(mc_amd->mpb, src->mpb, src->mpb_size); - memcpy(mc_amd->equiv_cpu_table, src->equiv_cpu_table, - src->equiv_cpu_table_size); - } - - return 1; - -err2: - xfree(mc_amd->equiv_cpu_table); -err1: - xfree(mc_amd); - uci->mc.mc_amd = NULL; - return -ENOMEM; -} - static int start_update(void) { #if CONFIG_HVM @@ -708,7 +633,6 @@ static int start_update(void) } static const struct microcode_ops microcode_amd_ops = { - .microcode_resume_match = microcode_resume_match, .cpu_request_microcode = cpu_request_microcode, .collect_cpu_info = collect_cpu_info, .apply_microcode = apply_microcode, diff --git a/xen/arch/x86/microcode_intel.c b/xen/arch/x86/microcode_intel.c index d3405a0..bf6497f 100644 --- a/xen/arch/x86/microcode_intel.c +++ b/xen/arch/x86/microcode_intel.c @@ -250,13 +250,13 @@ static int microcode_sanity_check(void *mc) static bool match_cpu(const struct microcode_patch *patch) { - const struct ucode_cpu_info *uci = &this_cpu(ucode_cpu_info); + const struct cpu_signature *sig = &this_cpu(cpu_sig); if ( !patch ) return false; - return microcode_update_match(&patch->mc_intel->hdr, uci->cpu_sig.sig, - uci->cpu_sig.pf, uci->cpu_sig.rev) == NEW_UCODE; + return microcode_update_match(&patch->mc_intel->hdr, + sig->sig, sig->pf, sig->rev) == NEW_UCODE; } static void free_patch(struct microcode_patch *patch) @@ -281,7 +281,6 @@ static enum microcode_match_result compare_patch( */ static int get_matching_microcode(const void *mc, unsigned int cpu) { - struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu); const struct microcode_header_intel *mc_header = mc; unsigned long total_size = get_totalsize(mc_header); void *new_mc = xmalloc_bytes(total_size); @@ -308,17 +307,7 @@ static int get_matching_microcode(const void *mc, unsigned int cpu) pr_debug("microcode: CPU%d found a matching microcode update with" " version %#x (current=%#x)\n", - cpu, mc_header->rev, uci->cpu_sig.rev); - new_mc = xmalloc_bytes(total_size); - if ( new_mc == NULL ) - { - printk(KERN_ERR "microcode: error! Can not allocate memory\n"); - return -ENOMEM; - } - - memcpy(new_mc, mc, total_size); - xfree(uci->mc.mc_intel); - uci->mc.mc_intel = new_mc; + cpu, mc_header->rev, this_cpu(cpu_sig).rev); return 1; } @@ -329,7 +318,7 @@ static int apply_microcode(unsigned int cpu) uint64_t msr_content; unsigned int val[2]; unsigned int cpu_num = raw_smp_processor_id(); - struct ucode_cpu_info *uci = &per_cpu(ucode_cpu_info, cpu_num); + struct cpu_signature *sig = &per_cpu(cpu_sig, cpu); const struct microcode_intel *mc_intel; const struct microcode_patch *patch = microcode_get_cache(); @@ -360,16 +349,16 @@ 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 = %04x-%02x-%02x \n", - cpu_num, uci->cpu_sig.rev, val[1], + cpu_num, sig->rev, val[1], mc_intel->hdr.year, mc_intel->hdr.month, mc_intel->hdr.day); - uci->cpu_sig.rev = val[1]; + sig->rev = val[1]; return 0; } @@ -440,13 +429,7 @@ static int cpu_request_microcode(unsigned int cpu, const void *buf, return error; } -static int microcode_resume_match(unsigned int cpu, const void *mc) -{ - return get_matching_microcode(mc, cpu); -} - static const struct microcode_ops microcode_intel_ops = { - .microcode_resume_match = microcode_resume_match, .cpu_request_microcode = cpu_request_microcode, .collect_cpu_info = collect_cpu_info, .apply_microcode = apply_microcode, diff --git a/xen/arch/x86/spec_ctrl.c b/xen/arch/x86/spec_ctrl.c index 5d98cac..43128c3 100644 --- a/xen/arch/x86/spec_ctrl.c +++ b/xen/arch/x86/spec_ctrl.c @@ -436,7 +436,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 = this_cpu(ucode_cpu_info).cpu_sig.rev; + unsigned int ucode_rev = this_cpu(cpu_sig).rev; if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD ) return true; diff --git a/xen/include/asm-x86/microcode.h b/xen/include/asm-x86/microcode.h index 6541c58..f2ac509 100644 --- a/xen/include/asm-x86/microcode.h +++ b/xen/include/asm-x86/microcode.h @@ -10,7 +10,6 @@ enum microcode_match_result { }; struct cpu_signature; -struct ucode_cpu_info; struct microcode_patch { union { @@ -20,7 +19,6 @@ struct microcode_patch { }; struct microcode_ops { - int (*microcode_resume_match)(unsigned int cpu, const void *mc); int (*cpu_request_microcode)(unsigned int cpu, const void *buf, size_t size); int (*collect_cpu_info)(unsigned int cpu, struct cpu_signature *csig); @@ -39,16 +37,7 @@ struct cpu_signature { unsigned int rev; }; -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; const struct microcode_patch *microcode_get_cache(void); -- 1.8.3.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
next prev parent reply other threads:[~2019-05-27 8:27 UTC|newest] Thread overview: 64+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-05-27 8:31 [PATCH v7 00/10] improve late microcode loading Chao Gao 2019-05-27 8:31 ` [Xen-devel] " Chao Gao 2019-05-27 8:31 ` [PATCH v7 01/10] misc/xen-ucode: Upload a microcode blob to the hypervisor Chao Gao 2019-05-27 8:31 ` [Xen-devel] " Chao Gao 2019-06-04 16:14 ` Andrew Cooper 2019-06-04 16:23 ` Jan Beulich 2019-06-06 2:29 ` Chao Gao 2019-05-27 8:31 ` [PATCH v7 02/10] microcode/intel: extend microcode_update_match() Chao Gao 2019-05-27 8:31 ` [Xen-devel] " Chao Gao 2019-06-04 14:39 ` Jan Beulich 2019-06-05 13:22 ` Roger Pau Monné 2019-06-05 14:16 ` Jan Beulich 2019-06-06 8:26 ` Chao Gao 2019-06-06 9:01 ` Jan Beulich 2019-05-27 8:31 ` [PATCH v7 03/10] microcode: introduce a global cache of ucode patch Chao Gao 2019-05-27 8:31 ` [Xen-devel] " Chao Gao 2019-06-04 15:03 ` Jan Beulich 2019-06-10 5:33 ` Chao Gao 2019-06-11 6:50 ` Jan Beulich 2019-05-27 8:31 ` Chao Gao [this message] 2019-05-27 8:31 ` [Xen-devel] [PATCH v7 04/10] microcode: remove struct ucode_cpu_info Chao Gao 2019-06-04 15:13 ` Jan Beulich 2019-06-10 7:19 ` Chao Gao 2019-05-27 8:31 ` [PATCH v7 05/10] microcode: remove pointless 'cpu' parameter Chao Gao 2019-05-27 8:31 ` [Xen-devel] " Chao Gao 2019-06-04 15:29 ` Jan Beulich 2019-06-10 7:31 ` Chao Gao 2019-05-27 8:31 ` [PATCH v7 06/10] microcode: split out apply_microcode() from cpu_request_microcode() Chao Gao 2019-05-27 8:31 ` [Xen-devel] " Chao Gao 2019-06-05 12:37 ` Jan Beulich 2019-06-11 3:32 ` Chao Gao 2019-06-11 7:08 ` Jan Beulich 2019-06-11 8:53 ` Chao Gao 2019-06-11 9:15 ` Jan Beulich 2019-05-27 8:31 ` [PATCH v7 07/10] microcode/intel: Writeback and invalidate caches before updating microcode Chao Gao 2019-05-27 8:31 ` [Xen-devel] " Chao Gao 2019-06-05 13:20 ` Jan Beulich 2019-05-27 8:31 ` [PATCH v7 08/10] x86/microcode: Synchronize late microcode loading Chao Gao 2019-05-27 8:31 ` [Xen-devel] " Chao Gao 2019-06-05 14:09 ` Jan Beulich 2019-06-11 12:36 ` Chao Gao 2019-06-11 12:58 ` Jan Beulich 2019-06-11 15:47 ` Raj, Ashok 2019-06-05 14:42 ` Roger Pau Monné 2019-05-27 8:31 ` [PATCH v7 09/10] microcode: remove microcode_update_lock Chao Gao 2019-05-27 8:31 ` [Xen-devel] " Chao Gao 2019-06-05 14:52 ` Roger Pau Monné 2019-06-05 15:15 ` Jan Beulich 2019-06-05 14:53 ` Jan Beulich 2019-06-11 12:46 ` Chao Gao 2019-06-11 13:23 ` Jan Beulich 2019-06-11 16:04 ` Raj, Ashok 2019-06-12 7:38 ` Jan Beulich 2019-06-13 14:05 ` Chao Gao 2019-06-13 14:08 ` Jan Beulich 2019-06-13 14:58 ` Chao Gao 2019-06-13 17:47 ` Raj, Ashok 2019-06-14 8:58 ` Jan Beulich 2019-05-27 8:31 ` [PATCH v7 10/10] x86/microcode: always collect_cpu_info() during boot Chao Gao 2019-05-27 8:31 ` [Xen-devel] " Chao Gao 2019-06-05 14:56 ` Roger Pau Monné 2019-06-11 13:02 ` Chao Gao 2019-06-05 15:05 ` Jan Beulich 2019-06-11 12:58 ` Chao Gao
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1558945891-3015-5-git-send-email-chao.gao@intel.com \ --to=chao.gao@intel.com \ --cc=andrew.cooper3@citrix.com \ --cc=ashok.raj@intel.com \ --cc=jbeulich@suse.com \ --cc=roger.pau@citrix.com \ --cc=sergey.dyasli@citrix.com \ --cc=wl@xen.org \ --cc=xen-devel@lists.xenproject.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).