From: dimm <dmitry.adamushko@gmail.com>
To: linux-kernel@vger.kernel.org
Cc: Ingo Molnar <mingo@elte.hu>, "H. Peter Anvin" <hpa@zytor.com>,
Mike Travis <travis@sgi.com>,
Tigran Aivazian <tigran@aivazian.fsnet.co.uk>,
Thomas Gleixner <tglx@linutronix.de>,
Borislav Petkov <borislav.petkov@amd.com>,
Andreas Mohr <andi@lisas.de>, Jack Steiner <steiner@sgi.com>
Subject: [ RFC, PATCH - 1/2, v2 ] x86-microcode: refactor microcode output messages
Date: Mon, 02 Nov 2009 21:08:16 +0100 [thread overview]
Message-ID: <1257192496.5941.8.camel@dimm> (raw)
[ resending ]
Hi,
this is in response to Mike's patch "Limit the number of microcode
messages".
What's about the following (yet preliminary and not thoroughly tested)
approach?
patch-1:
simplify 'struct ucode_cpu_info' and related functional logic.
patch-2:
reduce a number of similar 'microcode version' messages by printing a
single message for all cpus with equal microcode version, like:
(1)
[ 96.589437] microcode: original microcode versions...
[ 96.589451] microcode: CPU0-1: sig=0x6f2, pf=0x20, revision=0x57
(2)
[ 96.603176] microcode: microcode versions after update...
[ 96.603193] microcode: CPU0-1: sig=0x6f2, pf=0x20, revision=0x57
The new approach is used in microcode_init() [ i.e. when loading a
module ] and microcode_write(), that's when we update all the cpus at
once.
reload_for_cpu() and update-all-cpus-upon-resuming() use the old
approach - a new microcode version is being reported upon applying it.
The latter might employ the similar 'report-for-all' approach as above
but that would somewhat complicate the logic. Anyways, there are plenty
of per-cpu messages upon system resuming so having some more
update-microcode related ones won't harm that muc, I guess :-)
(Not-yet-)signed-off-by: Dmitry Adaushko <dmitry.adamushko@gmail.com>
---
diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
index ef51b50..68fd54c 100644
--- a/arch/x86/include/asm/microcode.h
+++ b/arch/x86/include/asm/microcode.h
@@ -31,8 +31,6 @@ struct microcode_ops {
};
struct ucode_cpu_info {
- struct cpu_signature cpu_sig;
- int valid;
void *mc;
};
extern struct ucode_cpu_info ucode_cpu_info[];
diff --git a/arch/x86/kernel/microcode_amd.c b/arch/x86/kernel/microcode_amd.c
index 366baa1..c205d37 100644
--- a/arch/x86/kernel/microcode_amd.c
+++ b/arch/x86/kernel/microcode_amd.c
@@ -156,8 +156,6 @@ static int apply_microcode_amd(int cpu)
printk(KERN_INFO "microcode: CPU%d: updated (new patch_level=0x%x)\n",
cpu, rev);
- uci->cpu_sig.rev = rev;
-
return 0;
}
@@ -249,14 +247,18 @@ static enum ucode_state
generic_load_microcode(int cpu, const u8 *data, size_t size)
{
struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
+ struct cpu_signature cpu_sig;
const u8 *ucode_ptr = data;
- void *new_mc = NULL;
- void *mc;
- int new_rev = uci->cpu_sig.rev;
- unsigned int leftover;
+ void *new_mc = NULL, *mc;
+ unsigned int leftover, new_rev;
unsigned long offset;
enum ucode_state state = UCODE_OK;
+ if (collect_cpu_info_amd(cpu, &cpu_sig))
+ return UCODE_ERROR;
+
+ new_rev = cpu_sig.rev;
+
offset = install_equiv_cpu_table(ucode_ptr);
if (!offset) {
printk(KERN_ERR "microcode: failed to create "
@@ -293,7 +295,7 @@ generic_load_microcode(int cpu, const u8 *data, size_t size)
uci->mc = new_mc;
pr_debug("microcode: CPU%d found a matching microcode "
"update with version 0x%x (current=0x%x)\n",
- cpu, new_rev, uci->cpu_sig.rev);
+ cpu, new_rev, cpu_sig.rev);
} else {
vfree(new_mc);
state = UCODE_ERROR;
diff --git a/arch/x86/kernel/microcode_core.c b/arch/x86/kernel/microcode_core.c
index 378e9a8..b7ead3a 100644
--- a/arch/x86/kernel/microcode_core.c
+++ b/arch/x86/kernel/microcode_core.c
@@ -138,20 +138,6 @@ static int collect_cpu_info_on_target(int cpu, struct cpu_signature *cpu_sig)
return ret;
}
-static int collect_cpu_info(int cpu)
-{
- struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
- int ret;
-
- memset(uci, 0, sizeof(*uci));
-
- ret = collect_cpu_info_on_target(cpu, &uci->cpu_sig);
- if (!ret)
- uci->valid = 1;
-
- return ret;
-}
-
struct apply_microcode_ctx {
int err;
};
@@ -182,12 +168,8 @@ static int do_microcode_update(const void __user *buf, size_t size)
int cpu;
for_each_online_cpu(cpu) {
- struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
enum ucode_state ustate;
- if (!uci->valid)
- continue;
-
ustate = microcode_ops->request_microcode_user(cpu, buf, size);
if (ustate == UCODE_ERROR) {
error = -1;
@@ -269,23 +251,16 @@ static struct platform_device *microcode_pdev;
static int reload_for_cpu(int cpu)
{
- struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
- int err = 0;
+ enum ucode_state ustate;
mutex_lock(µcode_mutex);
- if (uci->valid) {
- enum ucode_state ustate;
- ustate = microcode_ops->request_microcode_fw(cpu, µcode_pdev->dev);
- if (ustate == UCODE_OK)
- apply_microcode_on_target(cpu);
- else
- if (ustate == UCODE_ERROR)
- err = -EINVAL;
- }
+ ustate = microcode_ops->request_microcode_fw(cpu, µcode_pdev->dev);
+ if (ustate == UCODE_OK)
+ apply_microcode_on_target(cpu);
mutex_unlock(µcode_mutex);
- return err;
+ return (ustate == UCODE_ERROR)? -EINVAL : 0;
}
static ssize_t reload_store(struct sys_device *dev,
@@ -317,17 +292,23 @@ static ssize_t reload_store(struct sys_device *dev,
static ssize_t version_show(struct sys_device *dev,
struct sysdev_attribute *attr, char *buf)
{
- struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
+ struct cpu_signature cpu_sig;
- return sprintf(buf, "0x%x\n", uci->cpu_sig.rev);
+ if (collect_cpu_info_on_target(dev->id, &cpu_sig))
+ return 0;
+
+ return sprintf(buf, "0x%x\n", cpu_sig.rev);
}
static ssize_t pf_show(struct sys_device *dev,
struct sysdev_attribute *attr, char *buf)
{
- struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
+ struct cpu_signature cpu_sig;
+
+ if (collect_cpu_info_on_target(dev->id, &cpu_sig))
+ return 0;
- return sprintf(buf, "0x%x\n", uci->cpu_sig.pf);
+ return sprintf(buf, "0x%x\n", cpu_sig.pf);
}
static SYSDEV_ATTR(reload, 0200, NULL, reload_store);
@@ -348,10 +329,7 @@ static struct attribute_group mc_attr_group = {
static void microcode_fini_cpu(int cpu)
{
- struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
-
microcode_ops->microcode_fini_cpu(cpu);
- uci->valid = 0;
}
static enum ucode_state microcode_resume_cpu(int cpu)
@@ -369,10 +347,10 @@ static enum ucode_state microcode_resume_cpu(int cpu)
static enum ucode_state microcode_init_cpu(int cpu)
{
+ struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
enum ucode_state ustate;
- if (collect_cpu_info(cpu))
- return UCODE_ERROR;
+ memset(uci, 0, sizeof(*uci));
/* --dimm. Trigger a delayed update? */
if (system_state != SYSTEM_RUNNING)
@@ -388,19 +366,6 @@ static enum ucode_state microcode_init_cpu(int cpu)
return ustate;
}
-static enum ucode_state microcode_update_cpu(int cpu)
-{
- struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
- enum ucode_state ustate;
-
- if (uci->valid)
- ustate = microcode_resume_cpu(cpu);
- else
- ustate = microcode_init_cpu(cpu);
-
- return ustate;
-}
-
static int mc_sysdev_add(struct sys_device *sys_dev)
{
int err, cpu = sys_dev->id;
@@ -450,7 +415,7 @@ static int mc_sysdev_resume(struct sys_device *dev)
*/
WARN_ON(cpu != 0);
- if (uci->valid && uci->mc)
+ if (uci->mc)
microcode_ops->apply_microcode(cpu);
return 0;
@@ -472,7 +437,10 @@ mc_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu)
switch (action) {
case CPU_ONLINE:
case CPU_ONLINE_FROZEN:
- microcode_update_cpu(cpu);
+ if (action == CPU_ONLINE_FROZEN)
+ microcode_resume_cpu(cpu);
+ else
+ microcode_init_cpu(cpu);
case CPU_DOWN_FAILED:
case CPU_DOWN_FAILED_FROZEN:
pr_debug("microcode: CPU%d added\n", cpu);
diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c
index 0d334dd..6589765 100644
--- a/arch/x86/kernel/microcode_intel.c
+++ b/arch/x86/kernel/microcode_intel.c
@@ -339,8 +339,6 @@ static int apply_microcode(int cpu)
mc_intel->hdr.date >> 24,
(mc_intel->hdr.date >> 16) & 0xff);
- uci->cpu_sig.rev = val[1];
-
return 0;
}
@@ -348,11 +346,16 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
int (*get_ucode_data)(void *, const void *, size_t))
{
struct ucode_cpu_info *uci = ucode_cpu_info + cpu;
+ struct cpu_signature cpu_sig;
u8 *ucode_ptr = data, *new_mc = NULL, *mc;
- int new_rev = uci->cpu_sig.rev;
- unsigned int leftover = size;
+ unsigned int leftover = size, new_rev;
enum ucode_state state = UCODE_OK;
+ if (collect_cpu_info(cpu, &cpu_sig))
+ return UCODE_ERROR;
+
+ new_rev = cpu_sig.rev;
+
while (leftover) {
struct microcode_header_intel mc_header;
unsigned int mc_size;
@@ -377,7 +380,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
break;
}
- if (get_matching_microcode(&uci->cpu_sig, mc, new_rev)) {
+ if (get_matching_microcode(&cpu_sig, mc, new_rev)) {
if (new_mc)
vfree(new_mc);
new_rev = mc_header.rev;
@@ -407,7 +410,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size,
pr_debug("microcode: CPU%d found a matching microcode update with"
" version 0x%x (current=0x%x)\n",
- cpu, new_rev, uci->cpu_sig.rev);
+ cpu, new_rev, cpu_sig.rev);
out:
return state;
}
next reply other threads:[~2009-11-02 20:08 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-11-02 20:08 dimm [this message]
2009-11-04 12:27 ` [ RFC, PATCH - 1/2, v2 ] x86-microcode: refactor microcode output messages Ingo Molnar
2009-11-05 15:37 ` Andreas Herrmann
2009-11-05 18:40 ` Dmitry Adamushko
2009-11-06 12:34 ` Andreas Herrmann
2009-11-06 12:56 ` Dmitry Adamushko
2009-11-06 19:46 ` Andreas Herrmann
2009-11-07 12:22 ` Dmitry Adamushko
2009-11-11 16:07 ` Dmitry Adamushko
2009-11-11 19:38 ` Andreas Herrmann
2009-11-12 11:33 ` Ingo Molnar
2009-11-12 11:54 ` Dmitry Adamushko
2009-11-12 12:06 ` Dmitry Adamushko
2009-11-12 15:20 ` Andreas Herrmann
2009-11-12 15:48 ` Dmitry Adamushko
2009-11-12 17:09 ` Borislav Petkov
2009-11-17 7:06 ` [PATCH] x86, ucode-amd: Move family check to microcde_amd.c's init function Andreas Herrmann
2009-11-17 9:24 ` [tip:x86/microcode] x86: " tip-bot for Andreas Herrmann
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=1257192496.5941.8.camel@dimm \
--to=dmitry.adamushko@gmail.com \
--cc=andi@lisas.de \
--cc=borislav.petkov@amd.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=steiner@sgi.com \
--cc=tglx@linutronix.de \
--cc=tigran@aivazian.fsnet.co.uk \
--cc=travis@sgi.com \
/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: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.