From nobody Thu Nov 21 11:35:17 2024 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 08EF813C83D for ; Wed, 20 Nov 2024 18:58:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.10 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732129120; cv=none; b=N5gfZgvUSx/1xJLbJUAEGA50l6uq7dUCNOllwQcqeX1YxHoKnj27gFdOtZhA1mEjABGoSH5DOXpOfJ+L/xAGF59BmoA3iRB+378ertVAa1CryDwUDBQg5gF6qyLtNnah5rwEUngKHYofsNna6jFGa5QywmkcxA5RrWpbYDk9wDg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1732129120; c=relaxed/simple; bh=VeBxinHA/9374g7DH+1EAYI5hUfV4y2iH1GEoe0D7M8=; h=Subject:To:Cc:From:Date:Message-Id; b=pZzKfTC1wDz3YNufGfUgHb3rHxk6jSHzTzrrBS065Or2Bhd1pSJhPsunboUsmZ1BsVRIw5N1goaI0SE0e5lUCXXYMwpJ8VRXoCCkr4xEkHS2i4EIz85FH53B61pf+t+z5bUpq2/PHieEVSxryniGnGmbWMafGmivicHA3asYsak= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com; spf=none smtp.mailfrom=linux.intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=Be5mKkOq; arc=none smtp.client-ip=192.198.163.10 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=linux.intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="Be5mKkOq" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1732129117; x=1763665117; h=subject:to:cc:from:date:message-id; bh=VeBxinHA/9374g7DH+1EAYI5hUfV4y2iH1GEoe0D7M8=; b=Be5mKkOqql5vYZrDZ3ZiV8fZMdt//SPMsjzzMxRAzITilf1T/K/pD0FC ehz+LeowrC8tIgAB5jRqxh5V0QN+QksCzwz7eKnWIm7LqDs5xqGwJjUZJ QeaEGqgj3FsW6gizQ1T5rmJyBdtRDxFFZIxHCLMChtKw1xCZGJKPNjDCn APjC5o2zxfr1M7dbq+4c6eWmEITFtFjGIr+xie/9rBFTtTfAKNzw0W9Lh oj1fbhdhiExs2H9aIo6aqcqROhrRlo896e7Vd7UsUCtVt1rLNTqDycrfw +lfq3u2zbmwEk7tw9GLvg6HmenDjBdPmQas5VA9c2FjzpXTW+9x1KGZLR w==; X-CSE-ConnectionGUID: lz4CAH5+SXWNQrW+ep+ruQ== X-CSE-MsgGUID: DGTfN/qmRJ6nZBBAJ8hF7A== X-IronPort-AV: E=McAfee;i="6700,10204,11262"; a="43608654" X-IronPort-AV: E=Sophos;i="6.12,170,1728975600"; d="scan'208";a="43608654" Received: from fmviesa009.fm.intel.com ([10.60.135.149]) by fmvoesa104.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 20 Nov 2024 10:58:36 -0800 X-CSE-ConnectionGUID: IYPiWoMGS8CX0f+psG/avg== X-CSE-MsgGUID: FV2kIuavTKSMoYODxxK2aw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.12,170,1728975600"; d="scan'208";a="90412541" Received: from davehans-spike.ostc.intel.com (HELO localhost.localdomain) ([10.165.164.11]) by fmviesa009.fm.intel.com with ESMTP; 20 Nov 2024 10:58:36 -0800 Subject: [PATCH] [v2] x86/cpu: Help users notice when running old Intel microcode To: linux-kernel@vger.kernel.org Cc: x86@kernel.org,tglx@linutronix.de,bp@alien8.de,alex.murray@canonical.com,andrew.cooper3@citrix.com,Dave Hansen From: Dave Hansen Date: Wed, 20 Nov 2024 10:58:35 -0800 Message-Id: <20241120185835.485F3BDA@davehans-spike.ostc.intel.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Changes from v1: - Flesh out changelog - Add Documentation/ - add_taint() and pr_warn() in addition to vulnerabilities/ file - Add checks for running under VMMs. Do not taint and report vulnerability as unknown. From: Dave Hansen Old microcode is bad for users and for kernel developers. For users, it exposes them to known fixed security and/or functional issues. These obviously rarely result in instant dumpster fires in every environment. But it is as important to keep your microcode up to date as it is to keep your kernel up to date. Old microcode also makes kernels harder to debug. A developer looking at an oops need to consider kernel bugs, known CPU issues and unknown CPU issues as possible causes. If they know the microcode is up to date, they can mostly eliminate known CPU issues as the cause. Make it easier to tell if CPU microcode is out of date. Add a list of released microcode. If the loaded microcode is older than the release, tell users in a place that folks can find it: /sys/devices/system/cpu/vulnerabilities/old_microcode Tell kernel kernel developers about it with the existing taint flag: TAINT_CPU_OUT_OF_SPEC =3D=3D Discussion =3D=3D When a user reports a potential kernel issue, it is very common to ask them to reproduce the issue on mainline. Running mainline, they will (independently from the distro) acquire a more up-to-date microcode version list. If their microcode is old, they will get a warning about the taint and kernel developers can take that into consideration when debugging. Just like any other entry in "vulnerabilities/", users are free to make their own assessment of their exposure. =3D=3D Microcode Revision Discussion =3D=3D The microcode versions in the table were generated from the Intel microcode git repo: 29f82f7429c ("microcode-20241029 Release") which as of this writing lags behind the latest microcode-20241112. It can be argued that the versions that the kernel picks to call "old" should be a revision or two old. Which specific version is picked is less important to me than picking *a* version and enforcing it. This repository contains only microcode versions that Intel has deemed to be OS-loadable. It is quite possible that the BIOS has loaded a newer microcode than the latest in this repo. If this happens, the system is considered to have new microcode, not old. Specifically, the sysfs file and taint flag answer the question: Is the CPU running on the latest OS-loadable microcode, or something even later that the BIOS loaded? In other words, Intel never publishes an authoritative list of CPUs and latest microcode revisions. Until it does, this is the best that Linux can do. Also note that the "intel-ucode-defs.h" file is simple, ugly and has lots of magic numbers. That's on purpose and should allow a single file to be shared across lots of stable kernel regardless of if they have the new "VFM" infrastructure or not. It was generated with a dumb script. =3D=3D FAQ =3D=3D Q: Does this tell me if my system is secure or insecure? A: No. It only tells you if your microcode is old. Q: Should the kernel warn if the microcode list itself is too old? A: No. New kernels will get new microcode lists, both mainline and stable. The only way to have an old list is to be running an old kernel in which case you have bigger problems. Q: Is this for security or functional issues? A: Both. Q: If a given microcode update only has functional problems but no security issues, will it be considered old? A: Yes. All microcode image versions within a microcode release are treated identically. Intel appears to make security updates without disclosing them in the release notes. Thus, all updates are considered to be security-relevant. Q: Who runs old microcode? A: Anybody with an old distro. This happens all the time inside of Intel where there are lots of weird systems in labs that might not be getting regular distro updates and might also be running rather exotic microcode images. Signed-off-by: Dave Hansen --- b/Documentation/ABI/testing/sysfs-devices-system-cpu | 1=20 b/Documentation/admin-guide/hw-vuln/old_microcode.rst | 18 ++ b/arch/x86/include/asm/cpufeatures.h | 1=20 b/arch/x86/kernel/cpu/bugs.c | 16 + b/arch/x86/kernel/cpu/common.c | 38 ++++ b/arch/x86/kernel/cpu/microcode/intel-ucode-defs.h | 150 +++++++++++++= +++++ b/drivers/base/cpu.c | 3=20 b/include/linux/cpu.h | 2=20 8 files changed, 229 insertions(+) diff -puN arch/x86/include/asm/cpufeatures.h~old-ucode-0 arch/x86/include/a= sm/cpufeatures.h --- a/arch/x86/include/asm/cpufeatures.h~old-ucode-0 2024-11-20 08:50:13.85= 8811785 -0800 +++ b/arch/x86/include/asm/cpufeatures.h 2024-11-20 08:50:13.878812551 -0800 @@ -525,4 +525,5 @@ #define X86_BUG_RFDS X86_BUG(1*32 + 2) /* "rfds" CPU is vulnerable to Re= gister File Data Sampling */ #define X86_BUG_BHI X86_BUG(1*32 + 3) /* "bhi" CPU is affected by Branch= History Injection */ #define X86_BUG_IBPB_NO_RET X86_BUG(1*32 + 4) /* "ibpb_no_ret" IBPB om= its return target predictions */ +#define X86_BUG_OLD_MICROCODE X86_BUG(1*32 + 5) /* "old_microcode" CPU ha= s old microcode, it is surely vulnerable to something */ #endif /* _ASM_X86_CPUFEATURES_H */ diff -puN arch/x86/kernel/cpu/common.c~old-ucode-0 arch/x86/kernel/cpu/comm= on.c --- a/arch/x86/kernel/cpu/common.c~old-ucode-0 2024-11-20 08:50:13.85881178= 5 -0800 +++ b/arch/x86/kernel/cpu/common.c 2024-11-20 10:50:16.946011999 -0800 @@ -1318,10 +1318,48 @@ static bool __init vulnerable_to_rfds(u6 return cpu_matches(cpu_vuln_blacklist, RFDS); } =20 +struct x86_cpu_id cpu_latest_microcdoe[] =3D { +#include "microcode/intel-ucode-defs.h" + {} +}; + +static bool __init cpu_has_old_microcode(void) +{ + const struct x86_cpu_id *m =3D x86_match_cpu(cpu_latest_microcdoe); + + /* Give unknown CPUs a pass: */ + if (!m) + return false; + + /* + * Hosts usually lie to guests with a super high microcode + * version. Just ignore what hosts tell guests: + */ + if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) + return false; + + /* Consider all debug microcode to be old: */ + if (boot_cpu_data.microcode & BIT(31)) + return true; + + /* Give new microocode a pass: */ + if (boot_cpu_data.microcode >=3D m->driver_data) + return false; + + /* Uh oh, too old: */ + return true; +} + static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) { u64 x86_arch_cap_msr =3D x86_read_arch_cap_msr(); =20 + if (cpu_has_old_microcode()) { + pr_warn("x86/CPU: Running old microcode\n"); + setup_force_cpu_bug(X86_BUG_OLD_MICROCODE); + add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK); + } + /* Set ITLB_MULTIHIT bug if cpu is not in the whitelist and not mitigated= */ if (!cpu_matches(cpu_vuln_whitelist, NO_ITLB_MULTIHIT) && !(x86_arch_cap_msr & ARCH_CAP_PSCHANGE_MC_NO)) diff -puN arch/x86/kernel/cpu/microcode/intel-ucode-defs.h~old-ucode-0 arch= /x86/kernel/cpu/microcode/intel-ucode-defs.h --- a/arch/x86/kernel/cpu/microcode/intel-ucode-defs.h~old-ucode-0 2024-11-= 20 08:50:13.862811938 -0800 +++ b/arch/x86/kernel/cpu/microcode/intel-ucode-defs.h 2024-11-20 08:50:13.= 878812551 -0800 @@ -0,0 +1,150 @@ +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x03, .steppings =3D 0x0004, .driver_data =3D 0x= 2 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x05, .steppings =3D 0x0001, .driver_data =3D 0x= 45 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x05, .steppings =3D 0x0002, .driver_data =3D 0x= 40 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x05, .steppings =3D 0x0004, .driver_data =3D 0x= 2c }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x05, .steppings =3D 0x0008, .driver_data =3D 0x= 10 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x06, .steppings =3D 0x0001, .driver_data =3D 0x= a }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x06, .steppings =3D 0x0020, .driver_data =3D 0x= 3 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x06, .steppings =3D 0x0400, .driver_data =3D 0x= d }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x06, .steppings =3D 0x2000, .driver_data =3D 0x= 7 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x07, .steppings =3D 0x0002, .driver_data =3D 0x= 14 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x07, .steppings =3D 0x0004, .driver_data =3D 0x= 38 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x07, .steppings =3D 0x0008, .driver_data =3D 0x= 2e }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x08, .steppings =3D 0x0002, .driver_data =3D 0x= 11 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x08, .steppings =3D 0x0008, .driver_data =3D 0x= 8 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x08, .steppings =3D 0x0040, .driver_data =3D 0x= c }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x08, .steppings =3D 0x0400, .driver_data =3D 0x= 5 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x09, .steppings =3D 0x0020, .driver_data =3D 0x= 47 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x0a, .steppings =3D 0x0001, .driver_data =3D 0x= 3 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x0a, .steppings =3D 0x0002, .driver_data =3D 0x= 1 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x0b, .steppings =3D 0x0002, .driver_data =3D 0x= 1d }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x0b, .steppings =3D 0x0010, .driver_data =3D 0x= 2 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x0d, .steppings =3D 0x0040, .driver_data =3D 0x= 18 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x0e, .steppings =3D 0x0100, .driver_data =3D 0x= 39 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x0e, .steppings =3D 0x1000, .driver_data =3D 0x= 59 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x0f, .steppings =3D 0x0004, .driver_data =3D 0x= 5d }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x0f, .steppings =3D 0x0040, .driver_data =3D 0x= d2 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x0f, .steppings =3D 0x0080, .driver_data =3D 0x= 6b }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x0f, .steppings =3D 0x0400, .driver_data =3D 0x= 95 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x0f, .steppings =3D 0x0800, .driver_data =3D 0x= bc }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x0f, .steppings =3D 0x2000, .driver_data =3D 0x= a4 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x16, .steppings =3D 0x0002, .driver_data =3D 0x= 44 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x17, .steppings =3D 0x0040, .driver_data =3D 0x= 60f }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x17, .steppings =3D 0x0080, .driver_data =3D 0x= 70a }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x17, .steppings =3D 0x0400, .driver_data =3D 0x= a0b }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x1a, .steppings =3D 0x0010, .driver_data =3D 0x= 12 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x1a, .steppings =3D 0x0020, .driver_data =3D 0x= 1d }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x1c, .steppings =3D 0x0004, .driver_data =3D 0x= 219 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x1c, .steppings =3D 0x0400, .driver_data =3D 0x= 107 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x1d, .steppings =3D 0x0002, .driver_data =3D 0x= 29 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x1e, .steppings =3D 0x0020, .driver_data =3D 0x= a }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x25, .steppings =3D 0x0004, .driver_data =3D 0x= 11 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x25, .steppings =3D 0x0020, .driver_data =3D 0x= 7 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x26, .steppings =3D 0x0002, .driver_data =3D 0x= 105 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x2a, .steppings =3D 0x0080, .driver_data =3D 0x= 2f }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x2c, .steppings =3D 0x0004, .driver_data =3D 0x= 1f }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x2d, .steppings =3D 0x0040, .driver_data =3D 0x= 621 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x2d, .steppings =3D 0x0080, .driver_data =3D 0x= 71a }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x2e, .steppings =3D 0x0040, .driver_data =3D 0x= d }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x2f, .steppings =3D 0x0004, .driver_data =3D 0x= 3b }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x37, .steppings =3D 0x0100, .driver_data =3D 0x= 838 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x37, .steppings =3D 0x0200, .driver_data =3D 0x= 90d }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x3a, .steppings =3D 0x0200, .driver_data =3D 0x= 21 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x3c, .steppings =3D 0x0008, .driver_data =3D 0x= 28 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x3d, .steppings =3D 0x0010, .driver_data =3D 0x= 2f }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x3e, .steppings =3D 0x0010, .driver_data =3D 0x= 42e }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x3e, .steppings =3D 0x0040, .driver_data =3D 0x= 600 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x3e, .steppings =3D 0x0080, .driver_data =3D 0x= 715 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x3f, .steppings =3D 0x0004, .driver_data =3D 0x= 49 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x3f, .steppings =3D 0x0010, .driver_data =3D 0x= 1a }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x45, .steppings =3D 0x0002, .driver_data =3D 0x= 26 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x46, .steppings =3D 0x0002, .driver_data =3D 0x= 1c }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x47, .steppings =3D 0x0002, .driver_data =3D 0x= 22 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x4c, .steppings =3D 0x0008, .driver_data =3D 0x= 368 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x4c, .steppings =3D 0x0010, .driver_data =3D 0x= 411 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x4d, .steppings =3D 0x0100, .driver_data =3D 0x= 12d }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x4e, .steppings =3D 0x0008, .driver_data =3D 0x= f0 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x55, .steppings =3D 0x0008, .driver_data =3D 0x= 1000191 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x55, .steppings =3D 0x0010, .driver_data =3D 0x= 2007006 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x55, .steppings =3D 0x0020, .driver_data =3D 0x= 3000010 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x55, .steppings =3D 0x0040, .driver_data =3D 0x= 4003605 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x55, .steppings =3D 0x0080, .driver_data =3D 0x= 5003707 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x55, .steppings =3D 0x0800, .driver_data =3D 0x= 7002904 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x56, .steppings =3D 0x0004, .driver_data =3D 0x= 1c }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x56, .steppings =3D 0x0008, .driver_data =3D 0x= 700001c }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x56, .steppings =3D 0x0010, .driver_data =3D 0x= f00001a }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x56, .steppings =3D 0x0020, .driver_data =3D 0x= e000015 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x5c, .steppings =3D 0x0004, .driver_data =3D 0x= 14 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x5c, .steppings =3D 0x0200, .driver_data =3D 0x= 48 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x5c, .steppings =3D 0x0400, .driver_data =3D 0x= 28 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x5e, .steppings =3D 0x0008, .driver_data =3D 0x= f0 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x5f, .steppings =3D 0x0002, .driver_data =3D 0x= 3e }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x66, .steppings =3D 0x0008, .driver_data =3D 0x= 2a }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x6a, .steppings =3D 0x0020, .driver_data =3D 0x= c0002f0 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x6a, .steppings =3D 0x0040, .driver_data =3D 0x= d0003e7 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x6c, .steppings =3D 0x0002, .driver_data =3D 0x= 10002b0 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x7a, .steppings =3D 0x0002, .driver_data =3D 0x= 42 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x7a, .steppings =3D 0x0100, .driver_data =3D 0x= 24 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x7e, .steppings =3D 0x0020, .driver_data =3D 0x= c6 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x8a, .steppings =3D 0x0002, .driver_data =3D 0x= 33 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x8c, .steppings =3D 0x0002, .driver_data =3D 0x= b8 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x8c, .steppings =3D 0x0004, .driver_data =3D 0x= 38 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x8d, .steppings =3D 0x0002, .driver_data =3D 0x= 52 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x8e, .steppings =3D 0x0200, .driver_data =3D 0x= f6 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x8e, .steppings =3D 0x0400, .driver_data =3D 0x= f6 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x8e, .steppings =3D 0x0800, .driver_data =3D 0x= f6 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x8e, .steppings =3D 0x1000, .driver_data =3D 0x= fc }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x8f, .steppings =3D 0x0100, .driver_data =3D 0x= 2c000390 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x8f, .steppings =3D 0x0080, .driver_data =3D 0x= 2b0005c0 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x8f, .steppings =3D 0x0040, .driver_data =3D 0x= 2c000390 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x8f, .steppings =3D 0x0020, .driver_data =3D 0x= 2c000390 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x8f, .steppings =3D 0x0010, .driver_data =3D 0x= 2c000390 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x96, .steppings =3D 0x0002, .driver_data =3D 0x= 1a }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x97, .steppings =3D 0x0004, .driver_data =3D 0x= 36 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x97, .steppings =3D 0x0020, .driver_data =3D 0x= 36 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0xbf, .steppings =3D 0x0004, .driver_data =3D 0x= 36 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0xbf, .steppings =3D 0x0020, .driver_data =3D 0x= 36 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x9a, .steppings =3D 0x0008, .driver_data =3D 0x= 434 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x9a, .steppings =3D 0x0010, .driver_data =3D 0x= 434 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x9c, .steppings =3D 0x0001, .driver_data =3D 0x= 24000026 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x9e, .steppings =3D 0x0200, .driver_data =3D 0x= f8 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x9e, .steppings =3D 0x0400, .driver_data =3D 0x= f8 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x9e, .steppings =3D 0x0800, .driver_data =3D 0x= f6 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x9e, .steppings =3D 0x1000, .driver_data =3D 0x= f8 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0x9e, .steppings =3D 0x2000, .driver_data =3D 0x= 100 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0xa5, .steppings =3D 0x0004, .driver_data =3D 0x= fc }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0xa5, .steppings =3D 0x0008, .driver_data =3D 0x= fc }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0xa5, .steppings =3D 0x0020, .driver_data =3D 0x= fc }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0xa6, .steppings =3D 0x0001, .driver_data =3D 0x= fe }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0xa6, .steppings =3D 0x0002, .driver_data =3D 0x= fc }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0xa7, .steppings =3D 0x0002, .driver_data =3D 0x= 62 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0xaa, .steppings =3D 0x0010, .driver_data =3D 0x= 1f }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0xb7, .steppings =3D 0x0002, .driver_data =3D 0x= 12b }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0xba, .steppings =3D 0x0004, .driver_data =3D 0x= 4122 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0xba, .steppings =3D 0x0008, .driver_data =3D 0x= 4122 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0xba, .steppings =3D 0x0100, .driver_data =3D 0x= 4122 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0xbe, .steppings =3D 0x0001, .driver_data =3D 0x= 1a }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0xcf, .steppings =3D 0x0004, .driver_data =3D 0x= 21000230 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0x6, .model =3D 0xcf, .steppings =3D 0x0002, .driver_data =3D 0x= 21000230 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0xf, .model =3D 0x00, .steppings =3D 0x0080, .driver_data =3D 0x= 12 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0xf, .model =3D 0x00, .steppings =3D 0x0400, .driver_data =3D 0x= 15 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0xf, .model =3D 0x01, .steppings =3D 0x0004, .driver_data =3D 0x= 2e }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0xf, .model =3D 0x02, .steppings =3D 0x0010, .driver_data =3D 0x= 21 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0xf, .model =3D 0x02, .steppings =3D 0x0020, .driver_data =3D 0x= 2c }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0xf, .model =3D 0x02, .steppings =3D 0x0040, .driver_data =3D 0x= 10 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0xf, .model =3D 0x02, .steppings =3D 0x0080, .driver_data =3D 0x= 39 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0xf, .model =3D 0x02, .steppings =3D 0x0200, .driver_data =3D 0x= 2f }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0xf, .model =3D 0x03, .steppings =3D 0x0004, .driver_data =3D 0x= a }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0xf, .model =3D 0x03, .steppings =3D 0x0008, .driver_data =3D 0x= c }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0xf, .model =3D 0x03, .steppings =3D 0x0010, .driver_data =3D 0x= 17 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0xf, .model =3D 0x04, .steppings =3D 0x0002, .driver_data =3D 0x= 17 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0xf, .model =3D 0x04, .steppings =3D 0x0008, .driver_data =3D 0x= 5 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0xf, .model =3D 0x04, .steppings =3D 0x0010, .driver_data =3D 0x= 6 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0xf, .model =3D 0x04, .steppings =3D 0x0080, .driver_data =3D 0x= 3 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0xf, .model =3D 0x04, .steppings =3D 0x0100, .driver_data =3D 0x= e }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0xf, .model =3D 0x04, .steppings =3D 0x0200, .driver_data =3D 0x= 3 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0xf, .model =3D 0x04, .steppings =3D 0x0400, .driver_data =3D 0x= 4 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0xf, .model =3D 0x06, .steppings =3D 0x0004, .driver_data =3D 0x= f }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0xf, .model =3D 0x06, .steppings =3D 0x0010, .driver_data =3D 0x= 4 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0xf, .model =3D 0x06, .steppings =3D 0x0020, .driver_data =3D 0x= 8 }, +{ .flags =3D X86_CPU_ID_FLAG_ENTRY_VALID, .vendor =3D X86_VENDOR_INTEL, .f= amily =3D 0xf, .model =3D 0x06, .steppings =3D 0x0100, .driver_data =3D 0x= 9 }, diff -puN arch/x86/kernel/cpu/bugs.c~old-ucode-0 arch/x86/kernel/cpu/bugs.c --- a/arch/x86/kernel/cpu/bugs.c~old-ucode-0 2024-11-20 08:50:13.862811938 = -0800 +++ b/arch/x86/kernel/cpu/bugs.c 2024-11-20 10:44:03.659797287 -0800 @@ -2795,6 +2795,14 @@ static ssize_t rfds_show_state(char *buf return sysfs_emit(buf, "%s\n", rfds_strings[rfds_mitigation]); } =20 +static ssize_t old_microcode_show_state(char *buf) +{ + if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) + return sysfs_emit(buf, "Unknown: running under hypervisor"); + + return sysfs_emit(buf, "Vulnerable\n"); +} + static char *stibp_state(void) { if (spectre_v2_in_eibrs_mode(spectre_v2_enabled) && @@ -2977,6 +2985,9 @@ static ssize_t cpu_show_common(struct de case X86_BUG_RFDS: return rfds_show_state(buf); =20 + case X86_BUG_OLD_MICROCODE: + return old_microcode_show_state(buf); + default: break; } @@ -3056,6 +3067,11 @@ ssize_t cpu_show_reg_file_data_sampling( { return cpu_show_common(dev, attr, buf, X86_BUG_RFDS); } + +ssize_t cpu_show_old_microcode(struct device *dev, struct device_attribute= *attr, char *buf) +{ + return cpu_show_common(dev, attr, buf, X86_BUG_OLD_MICROCODE); +} #endif =20 void __warn_thunk(void) diff -puN drivers/base/cpu.c~old-ucode-0 drivers/base/cpu.c --- a/drivers/base/cpu.c~old-ucode-0 2024-11-20 08:50:13.866812092 -0800 +++ b/drivers/base/cpu.c 2024-11-20 08:50:13.878812551 -0800 @@ -599,6 +599,7 @@ CPU_SHOW_VULN_FALLBACK(retbleed); CPU_SHOW_VULN_FALLBACK(spec_rstack_overflow); CPU_SHOW_VULN_FALLBACK(gds); CPU_SHOW_VULN_FALLBACK(reg_file_data_sampling); +CPU_SHOW_VULN_FALLBACK(old_microcode); =20 static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL); @@ -614,6 +615,7 @@ static DEVICE_ATTR(retbleed, 0444, cpu_s static DEVICE_ATTR(spec_rstack_overflow, 0444, cpu_show_spec_rstack_overfl= ow, NULL); static DEVICE_ATTR(gather_data_sampling, 0444, cpu_show_gds, NULL); static DEVICE_ATTR(reg_file_data_sampling, 0444, cpu_show_reg_file_data_sa= mpling, NULL); +static DEVICE_ATTR(old_microcode, 0444, cpu_show_old_microcode, NULL); =20 static struct attribute *cpu_root_vulnerabilities_attrs[] =3D { &dev_attr_meltdown.attr, @@ -630,6 +632,7 @@ static struct attribute *cpu_root_vulner &dev_attr_spec_rstack_overflow.attr, &dev_attr_gather_data_sampling.attr, &dev_attr_reg_file_data_sampling.attr, + &dev_attr_old_microcode.attr, NULL }; =20 diff -puN include/linux/cpu.h~old-ucode-0 include/linux/cpu.h --- a/include/linux/cpu.h~old-ucode-0 2024-11-20 08:50:13.866812092 -0800 +++ b/include/linux/cpu.h 2024-11-20 08:50:13.878812551 -0800 @@ -77,6 +77,8 @@ extern ssize_t cpu_show_gds(struct devic struct device_attribute *attr, char *buf); extern ssize_t cpu_show_reg_file_data_sampling(struct device *dev, struct device_attribute *attr, char *buf); +extern ssize_t cpu_show_old_microcode(struct device *dev, + struct device_attribute *attr, char *buf); =20 extern __printf(4, 5) struct device *cpu_device_create(struct device *parent, void *drvdata, diff -puN Documentation/ABI/testing/sysfs-devices-system-cpu~old-ucode-0 Do= cumentation/ABI/testing/sysfs-devices-system-cpu --- a/Documentation/ABI/testing/sysfs-devices-system-cpu~old-ucode-0 2024-1= 1-20 08:50:13.870812245 -0800 +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu 2024-11-20 08:50:1= 3.878812551 -0800 @@ -516,6 +516,7 @@ What: /sys/devices/system/cpu/vulnerabi /sys/devices/system/cpu/vulnerabilities/mds /sys/devices/system/cpu/vulnerabilities/meltdown /sys/devices/system/cpu/vulnerabilities/mmio_stale_data + /sys/devices/system/cpu/vulnerabilities/old_microcode /sys/devices/system/cpu/vulnerabilities/reg_file_data_sampling /sys/devices/system/cpu/vulnerabilities/retbleed /sys/devices/system/cpu/vulnerabilities/spec_store_bypass diff -puN /dev/null Documentation/admin-guide/hw-vuln/old_microcode.rst --- /dev/null 2024-11-09 18:22:36.078468820 -0800 +++ b/Documentation/admin-guide/hw-vuln/old_microcode.rst 2024-11-20 08:50:= 13.878812551 -0800 @@ -0,0 +1,18 @@ +.. SPDX-License-Identifier: GPL-2.0 + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D +Old Microcode +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +The kernel keeps a table of released microcode. Systems that have +microcode older than this will say "Vulnerable". This means that the +system is vulnerable to some known CPU issue. It could be security or +functional, the kernel does not know or care. + +Update the CPU microcode to mitigate any exposure. This is usually +accomplished by updating the files in /lib/firmware/intel-ucode/ +via normal distribution updates. Intel also distributes these files +in a github repo: + + https://github.com/intel/Intel-Linux-Processor-Microcode-Data-Files.git + _