Source-Changes-D archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: CVS commit: src/sys/arch/x86/x86
On 2019/05/16 13:20, Jason Thorpe wrote:
>
>
>> On May 15, 2019, at 9:19 PM, Maxime Villard <max%m00nbsd.net@localhost> wrote:
>>
>> Le 16/05/2019 à 04:36, SAITOH Masanobu a écrit :
>>> Module Name: src
>>> Committed By: msaitoh
>>> Date: Thu May 16 02:36:30 UTC 2019
>>> Modified Files:
>>> src/sys/arch/x86/x86: procfs_machdep.c
>>> Log Message:
>>> Use ci_feat_val[7] instead of directly getting cpuid 7 edx.
>>> To generate a diff of this commit:
>>> cvs rdiff -u -r1.28 -r1.29 src/sys/arch/x86/x86/procfs_machdep.c
>>> Please note that diffs are not public domain; they are subject to the
>>> copyright notices on the relevant files.
>>
>> The microcode updates CPUID7, if you read ci_feat_val you have the
>> initial value, not the updated value. So reading CPUID7 was the right
>> thing to do.
>
> Should the microcode update procedure fix up the cached copy?
I think so, but our code doesn't do it.
There are some code which copy a cpuid value to ci_feat_val[] and
modify some bits for workaround and use the copy. ci_feat_val[]
is better than trusting current cpuid values for consistency.
We should provide user an interface to know the current behavior
of the kernel. I think ci_feat_val[] is the data to explain the
behavior. If so, we should use ci_feat_val[] in x86/procfs_machdep.c.
But, sadly, ci_feat_val[] is not updated, so it might better to
use real cpuid value than ci_feat_val[]. The latest x86/procfs_machdep.c
(rev. 1.31) refers ci_feat_val[0..6] and not refer ci_feat_val[7].
It's inconsistent.
If we update ci_feat_val, we should have callback function to
reflect the change. Callback is not required for many bits but
it's required for some others.
I have a code locally to know which bit is changed after updating
microcode:
--------------
Index: x86/cpu_ucode_intel.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/x86/cpu_ucode_intel.c,v
retrieving revision 1.17
diff -u -p -r1.17 cpu_ucode_intel.c
--- x86/cpu_ucode_intel.c 10 May 2019 18:21:01 -0000 1.17
+++ x86/cpu_ucode_intel.c 16 May 2019 04:28:13 -0000
@@ -178,9 +178,14 @@ cpu_ucode_intel_apply(struct cpu_ucode_s
{
uint32_t ucodetarget, oucodeversion, nucodeversion;
struct intel1_ucode_header *uh;
+ struct cpu_info *ci;
+ struct cpu_info oldci;
+ int i;
int platformid, cpuid, error;
size_t newbufsize = 0;
void *uha;
+ uint64_t msr = 0;
+ u_int descs[4];
if (sc->loader_version != CPU_UCODE_LOADER_INTEL1 ||
cpuno != CPU_UCODE_CURRENT_CPU)
@@ -221,15 +226,62 @@ cpu_ucode_intel_apply(struct cpu_ucode_s
intel_getcurrentucode(&nucodeversion, &platformid);
cpuid = curcpu()->ci_index;
- kpreempt_enable();
-
if (nucodeversion != ucodetarget) {
+ kpreempt_enable();
error = EIO;
goto out;
}
- printf("cpu %d: ucode 0x%x->0x%x\n", cpuid, oucodeversion,
- nucodeversion);
+ ci = curcpu();
+ oldci = *ci;
+#if 1
+ /*
+ * Update cpu_info.
+ *
+ * XXX cpu_probe() is currently not intended to call multiple time
+ * on a cpu.
+ */
+ cpu_probe(curcpu());
+#endif
+ if (ci->ci_max_cpuid >= 7) {
+ x86_cpuid(7, descs);
+ if (descs[3] & CPUID_SEF_ARCH_CAP)
+ msr = rdmsr(MSR_IA32_ARCH_CAPABILITIES);
+ }
+ kpreempt_enable();
+
+ if ((ci->ci_max_cpuid >= 7) && (descs[3] & CPUID_SEF_ARCH_CAP))
+ printf("cpu%d: MSR_IA32_ARCH_CAPABILITIES=0x%lx\n", cpuid,
+ msr);
+ printf("cpu%d: ucode 0x%x->0x%x\n", cpuid,
+ oucodeversion, nucodeversion);
+ for (i = 0; i < __arraycount(ci->ci_feat_val); i++) {
+ uint32_t old, new, dif, set, unset;
+
+ old = oldci.ci_feat_val[i];
+ new = ci->ci_feat_val[i];
+ if (old != new) {
+ printf("cpu%d: ci_feat_val[%d] changed from %08x to "
+ "%08x\n", cpuid, i, old, new);
+ dif = old ^ new;
+ set = new & dif;
+ unset = old & dif;
+
+ if (set != 0)
+ printf("cpu%d: set: %08x\n", cpuid, set);
+ if (unset != 0)
+ printf("cpu%d: unset: %08x\n", cpuid, unset);
+
+ /*
+ * Call hook if you want to do something.
+ *
+ * WARNING. If HyperThreading is enabled and the
+ * microcode is updated to new one, another CPU's
+ * feature bits also be changed and we cannot hook
+ * for the CPU here.
+ */
+ }
+ }
out:
if (newbufsize != 0)
--------------
(The same diff is at http://www.netbsd.org/~msaitoh/ucode-20190516-0.dif)
This code has some problems:
- It uses cpu_probe(). I think the function currently not intended to be
called multiple times (though it might be safe now).
- This is only for Intel.
- Currently, cpu_ucode_intel_apply() is intended not
to run in parallel on all CPUs. It makes harder to call
callback function. For AMD, it does by xc_broadcast().
I hope someone solve all of those problems...
> -- thorpej
>
--
-----------------------------------------------
SAITOH Masanobu (msaitoh%execsw.org@localhost
msaitoh%netbsd.org@localhost)
Home |
Main Index |
Thread Index |
Old Index