[tip:x86/apic] x86/apic: Annotate global config variables as "read-only after init"

2019-08-07 Thread tip-bot for Sean Christopherson
Commit-ID:  6444b40eeda4f78f57b255dd7ecb8d3e5936eea2
Gitweb: https://git.kernel.org/tip/6444b40eeda4f78f57b255dd7ecb8d3e5936eea2
Author: Sean Christopherson 
AuthorDate: Mon, 5 Aug 2019 14:21:34 -0700
Committer:  Thomas Gleixner 
CommitDate: Wed, 7 Aug 2019 15:24:21 +0200

x86/apic: Annotate global config variables as "read-only after init"

Mark the APIC's global config variables that are constant after boot as
__ro_after_init to help document that the majority of the APIC config is
not changed at runtime, and to harden the kernel a smidge.

Signed-off-by: Sean Christopherson 
Signed-off-by: Thomas Gleixner 
Link: 
https://lkml.kernel.org/r/20190805212134.12001-1-sean.j.christopher...@intel.com

---
 arch/x86/kernel/apic/apic.c | 26 +-
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 831274e3c09f..3a31875bd0a3 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -65,10 +65,10 @@ unsigned int num_processors;
 unsigned disabled_cpus;
 
 /* Processor that is doing the boot up */
-unsigned int boot_cpu_physical_apicid = -1U;
+unsigned int boot_cpu_physical_apicid __ro_after_init = -1U;
 EXPORT_SYMBOL_GPL(boot_cpu_physical_apicid);
 
-u8 boot_cpu_apic_version;
+u8 boot_cpu_apic_version __ro_after_init;
 
 /*
  * The highest APIC ID seen during enumeration.
@@ -85,13 +85,13 @@ physid_mask_t phys_cpu_present_map;
  * disable_cpu_apicid=, mostly used for the kdump 2nd kernel to
  * avoid undefined behaviour caused by sending INIT from AP to BSP.
  */
-static unsigned int disabled_cpu_apicid __read_mostly = BAD_APICID;
+static unsigned int disabled_cpu_apicid __ro_after_init = BAD_APICID;
 
 /*
  * This variable controls which CPUs receive external NMIs.  By default,
  * external NMIs are delivered only to the BSP.
  */
-static int apic_extnmi = APIC_EXTNMI_BSP;
+static int apic_extnmi __ro_after_init = APIC_EXTNMI_BSP;
 
 /*
  * Map cpu index to physical APIC ID
@@ -114,7 +114,7 @@ EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_acpiid);
 DEFINE_EARLY_PER_CPU_READ_MOSTLY(int, x86_cpu_to_logical_apicid, BAD_APICID);
 
 /* Local APIC was disabled by the BIOS and enabled by the kernel */
-static int enabled_via_apicbase;
+static int enabled_via_apicbase __ro_after_init;
 
 /*
  * Handle interrupt mode configuration register (IMCR).
@@ -172,23 +172,23 @@ static __init int setup_apicpmtimer(char *s)
 __setup("apicpmtimer", setup_apicpmtimer);
 #endif
 
-unsigned long mp_lapic_addr;
-int disable_apic;
+unsigned long mp_lapic_addr __ro_after_init;
+int disable_apic __ro_after_init;
 /* Disable local APIC timer from the kernel commandline or via dmi quirk */
 static int disable_apic_timer __initdata;
 /* Local APIC timer works in C2 */
-int local_apic_timer_c2_ok;
+int local_apic_timer_c2_ok __ro_after_init;
 EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok);
 
 /*
  * Debug level, exported for io_apic.c
  */
-int apic_verbosity;
+int apic_verbosity __ro_after_init;
 
-int pic_mode;
+int pic_mode __ro_after_init;
 
 /* Have we found an MP table */
-int smp_found_config;
+int smp_found_config __ro_after_init;
 
 static struct resource lapic_resource = {
.name = "Local APIC",
@@ -199,7 +199,7 @@ unsigned int lapic_timer_period = 0;
 
 static void apic_pm_activate(void);
 
-static unsigned long apic_phys;
+static unsigned long apic_phys __ro_after_init;
 
 /*
  * Get the LAPIC version
@@ -1278,7 +1278,7 @@ void __init sync_Arb_IDs(void)
APIC_INT_LEVELTRIG | APIC_DM_INIT);
 }
 
-enum apic_intr_mode_id apic_intr_mode;
+enum apic_intr_mode_id apic_intr_mode __ro_after_init;
 
 static int __init apic_intr_mode_select(void)
 {


[tip:x86/mm] x86/fault: Decode and print #PF oops in human readable form

2019-04-19 Thread tip-bot for Sean Christopherson
Commit-ID:  18ea35c5ed9921867194a8efc2a0ac2d5a3c7d2a
Gitweb: https://git.kernel.org/tip/18ea35c5ed9921867194a8efc2a0ac2d5a3c7d2a
Author: Sean Christopherson 
AuthorDate: Fri, 21 Dec 2018 13:36:57 -0800
Committer:  Ingo Molnar 
CommitDate: Fri, 19 Apr 2019 19:31:16 +0200

x86/fault: Decode and print #PF oops in human readable form

Linus pointed out that deciphering the raw #PF error code and printing
a more human readable message are two different things, and also that
printing the negative cases is mostly just noise[1].  For example, the
USER bit doesn't mean the fault originated in user code and stating
that an oops wasn't due to a protection keys violation isn't interesting
since an oops on a keys violation is a one-in-a-million scenario.

Remove the per-bit decoding of the error code and instead print:
  - the raw error code
  - why the fault occurred
  - the effective privilege level of the access
  - the type of access
  - whether the fault originated in user code or kernel code

This provides the user with the information needed to triage 99.9% of
oopses without polluting the log with useless information or conflating
the error_code with the CPL.

Sample output:

BUG: kernel NULL pointer dereference, address = 0008
#PF: supervisor-privileged instruction fetch from kernel code
#PF: error_code(0x0010) - not-present page

BUG: unable to handle page fault for address = beef
#PF: supervisor-privileged instruction fetch from kernel code
#PF: error_code(0x0010) - not-present page

BUG: unable to handle page fault for address = c923
#PF: supervisor-privileged write access from kernel code
#PF: error_code(0x000b) - reserved bit violation

[1] 
https://lkml.kernel.org/r/CAHk-=whk_fsnxvmvf1t2ffcap2wrvsybabrlqcwljycvhw6...@mail.gmail.com

Suggested-by: Linus Torvalds 
Signed-off-by: Sean Christopherson 
Cc: Andy Lutomirski 
Cc: Borislav Petkov 
Cc: Dave Hansen 
Cc: Peter Zijlstra 
Cc: Rik van Riel 
Cc: Thomas Gleixner 
Cc: Yu-cheng Yu 
Link: 
http://lkml.kernel.org/r/20181221213657.27628-3-sean.j.christopher...@intel.com
Signed-off-by: Ingo Molnar 
---
 arch/x86/mm/fault.c | 42 +++---
 1 file changed, 11 insertions(+), 31 deletions(-)

diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index df2c5cdef5c4..74c9204c5751 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -603,24 +603,9 @@ static void show_ldttss(const struct desc_ptr *gdt, const 
char *name, u16 index)
 name, index, addr, (desc.limit0 | (desc.limit1 << 16)));
 }
 
-/*
- * This helper function transforms the #PF error_code bits into
- * "[PROT] [USER]" type of descriptive, almost human-readable error strings:
- */
-static void err_str_append(unsigned long error_code, char *buf, unsigned long 
mask, const char *txt)
-{
-   if (error_code & mask) {
-   if (buf[0])
-   strcat(buf, " ");
-   strcat(buf, txt);
-   }
-}
-
 static void
 show_fault_oops(struct pt_regs *regs, unsigned long error_code, unsigned long 
address)
 {
-   char err_txt[64];
-
if (!oops_may_print())
return;
 
@@ -651,27 +636,22 @@ show_fault_oops(struct pt_regs *regs, unsigned long 
error_code, unsigned long ad
pr_alert("BUG: unable to handle page fault for address = %px\n",
(void *)address);
 
-   err_txt[0] = 0;
-
-   /*
-* Note: length of these appended strings including the separation 
space and the
-* zero delimiter must fit into err_txt[].
-*/
-   err_str_append(error_code, err_txt, X86_PF_PROT,  "[PROT]" );
-   err_str_append(error_code, err_txt, X86_PF_WRITE, "[WRITE]");
-   err_str_append(error_code, err_txt, X86_PF_USER,  "[USER]" );
-   err_str_append(error_code, err_txt, X86_PF_RSVD,  "[RSVD]" );
-   err_str_append(error_code, err_txt, X86_PF_INSTR, "[INSTR]");
-   err_str_append(error_code, err_txt, X86_PF_PK,"[PK]"   );
-
-   pr_alert("#PF error: %s\n", error_code ? err_txt : "[normal kernel read 
fault]");
+   pr_alert("#PF: %s-privileged %s from %s code\n",
+(error_code & X86_PF_USER)  ? "user" : "supervisor",
+(error_code & X86_PF_INSTR) ? "instruction fetch" :
+(error_code & X86_PF_WRITE) ? "write access" :
+  "read access",
+user_mode(regs) ? "user" : "kernel");
+   pr_alert("#PF: error_code(0x%04lx) - %s\n", error_code,
+!(error_code & X86_PF_PROT) ? "not-present page" :
+(error_code & X86_PF_RSVD)  ? "reserved bit violation" :
+(error_code & X86_PF_PK)? "protection keys violation" :
+  "permissions violation");
 
if (!(error_code & X86_PF_USER) && user_mode(regs)) {
struct desc_ptr idt, gdt;
  

[tip:x86/mm] x86/fault: Reword initial BUG message for unhandled page faults

2019-04-19 Thread tip-bot for Sean Christopherson
Commit-ID:  f28b11a2abd9cf5535baa03e28fc63ad0e14f52a
Gitweb: https://git.kernel.org/tip/f28b11a2abd9cf5535baa03e28fc63ad0e14f52a
Author: Sean Christopherson 
AuthorDate: Fri, 21 Dec 2018 13:36:56 -0800
Committer:  Ingo Molnar 
CommitDate: Fri, 19 Apr 2019 19:31:15 +0200

x86/fault: Reword initial BUG message for unhandled page faults

Reword the NULL pointer dereference case to simply state that a NULL
pointer was dereferenced, i.e. drop "unable to handle" as that implies
that there are instances where the kernel actual does handle NULL
pointer dereferences, which is not true barring funky exception fixup.

For the non-NULL case, replace "kernel paging request" with "page fault"
as the kernel can technically oops on faults that originated in user
code.  Dropping "kernel" also allows future patches to provide detailed
information on where the fault occurred, e.g. user vs. kernel, without
conflicting with the initial BUG message.

In both cases, replace "at address=" with wording more appropriate to
the oops, as "at" may be interpreted as stating that the address is the
RIP of the instruction that faulted.

Last, and probably least, further qualify the NULL-pointer path by
checking that the fault actually originated in kernel code.  It's
technically possible for userspace to map address 0, and not printing
a super specific message is the least of our worries if the kernel does
manage to oops on an actual NULL pointer dereference from userspace.

Before:
BUG: unable to handle kernel NULL pointer dereference at beef
BUG: unable to handle kernel paging request at beef

After:
BUG: kernel NULL pointer dereference, address = 0008
BUG: unable to handle page fault for address = beef

Suggested-by: Linus Torvalds 
Signed-off-by: Sean Christopherson 
Cc: Andy Lutomirski 
Cc: Borislav Petkov 
Cc: Dave Hansen 
Cc: Peter Zijlstra 
Cc: Rik van Riel 
Cc: Thomas Gleixner 
Cc: Yu-cheng Yu 
Link: 
http://lkml.kernel.org/r/20181221213657.27628-2-sean.j.christopher...@intel.com
Signed-off-by: Ingo Molnar 
---
 arch/x86/mm/fault.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 667f1da36208..df2c5cdef5c4 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -644,9 +644,12 @@ show_fault_oops(struct pt_regs *regs, unsigned long 
error_code, unsigned long ad
from_kuid(&init_user_ns, current_uid()));
}
 
-   pr_alert("BUG: unable to handle kernel %s at %px\n",
-address < PAGE_SIZE ? "NULL pointer dereference" : "paging 
request",
-(void *)address);
+   if (address < PAGE_SIZE && !user_mode(regs))
+   pr_alert("BUG: kernel NULL pointer dereference, address = 
%px\n",
+   (void *)address);
+   else
+   pr_alert("BUG: unable to handle page fault for address = %px\n",
+   (void *)address);
 
err_txt[0] = 0;
 


[tip:x86/asm] x86/vdso: Remove a stale/misleading comment from the linker script

2018-12-05 Thread tip-bot for Sean Christopherson
Commit-ID:  29434801e7e9c6d05fbea4533b3c0bd6be612f62
Gitweb: https://git.kernel.org/tip/29434801e7e9c6d05fbea4533b3c0bd6be612f62
Author: Sean Christopherson 
AuthorDate: Tue, 4 Dec 2018 13:25:58 -0800
Committer:  Ingo Molnar 
CommitDate: Wed, 5 Dec 2018 08:58:12 +0100

x86/vdso: Remove a stale/misleading comment from the linker script

Once upon a time, vdso2c aggressively stripped data from the vDSO
image when generating the final userspace image.  This included
stripping the .altinstructions and .altinstr_replacement sections.
Eventually, the stripping process reverted to "objdump -S" and no
longer removed the aforementioned sections, but the comment remained.

Keeping the .alt* sections at the end of the PT_LOAD segment is no
longer necessary, but there's no harm in doing so and it's a helpful
reminder that they don't need to be included in the final vDSO image,
i.e. someone may want to take another stab at zapping/stripping the
unneeded sections.

Signed-off-by: Sean Christopherson 
Acked-by: Andy Lutomirski 
Cc: Borislav Petkov 
Cc: Brian Gerst 
Cc: Dave Hansen 
Cc: Denys Vlasenko 
Cc: H. Peter Anvin 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Rik van Riel 
Cc: Thomas Gleixner 
Fixes: da861e18eccc ("x86, vdso: Get rid of the fake section mechanism")
Link: 
http://lkml.kernel.org/r/20181204212600.28090-3-sean.j.christopher...@intel.com
Signed-off-by: Ingo Molnar 
---
 arch/x86/entry/vdso/vdso-layout.lds.S | 5 -
 1 file changed, 5 deletions(-)

diff --git a/arch/x86/entry/vdso/vdso-layout.lds.S 
b/arch/x86/entry/vdso/vdso-layout.lds.S
index 0cedc905c8d6..93c6dc7812d0 100644
--- a/arch/x86/entry/vdso/vdso-layout.lds.S
+++ b/arch/x86/entry/vdso/vdso-layout.lds.S
@@ -65,11 +65,6 @@ SECTIONS
 
.text   : { *(.text*) } :text   =0x90909090,
 
-   /*
-* At the end so that eu-elflint stays happy when vdso2c strips
-* these.  A better implementation would avoid allocating space
-* for these.
-*/
.altinstructions: { *(.altinstructions) }   :text
.altinstr_replacement   : { *(.altinstr_replacement) }  :text
 


[tip:x86/asm] x86/vdso: Remove obsolete "fake section table" reservation

2018-12-05 Thread tip-bot for Sean Christopherson
Commit-ID:  24b7c77bbb24f129beead93574ff248c3db1288e
Gitweb: https://git.kernel.org/tip/24b7c77bbb24f129beead93574ff248c3db1288e
Author: Sean Christopherson 
AuthorDate: Tue, 4 Dec 2018 13:25:57 -0800
Committer:  Ingo Molnar 
CommitDate: Wed, 5 Dec 2018 08:58:11 +0100

x86/vdso: Remove obsolete "fake section table" reservation

At one point the vDSO image was manually stripped down by vdso2c in an
attempt to minimize the size of the image mapped into userspace.  Part
of that stripping process involved building a fake section table so as
not to break userspace processes that parse the section table.  Memory
for the fake section table was reserved in the .rodata section so that
vdso2c could simply copy the entire PT_LOAD segment into the userspace
image after building the fake table.

Eventually, the entire fake section table approach was dropped in favor
of stripping the vdso "the old fashioned way", i.e. via objdump -S.
But, the reservation in .rodata for the fake table was left behind.
Remove the reserveration along with a few other related defines and
section entries.

Removing the fake section table placeholder zaps a whopping 0x340 bytes
from the 64-bit vDSO image, which drops the current image's size to
under 4k, i.e. reduces the effective size of the userspace vDSO mapping
by a full page.

Signed-off-by: Sean Christopherson 
Acked-by: Andy Lutomirski 
Cc: Borislav Petkov 
Cc: Brian Gerst 
Cc: Dave Hansen 
Cc: Denys Vlasenko 
Cc: H. Peter Anvin 
Cc: Linus Torvalds 
Cc: Peter Zijlstra 
Cc: Rik van Riel 
Cc: Thomas Gleixner 
Fixes: da861e18eccc ("x86, vdso: Get rid of the fake section mechanism")
Link: 
http://lkml.kernel.org/r/20181204212600.28090-2-sean.j.christopher...@intel.com
Signed-off-by: Ingo Molnar 
---
 arch/x86/entry/vdso/vdso-layout.lds.S | 22 --
 arch/x86/entry/vdso/vdso2c.c  |  8 
 2 files changed, 30 deletions(-)

diff --git a/arch/x86/entry/vdso/vdso-layout.lds.S 
b/arch/x86/entry/vdso/vdso-layout.lds.S
index acfd5ba7d943..0cedc905c8d6 100644
--- a/arch/x86/entry/vdso/vdso-layout.lds.S
+++ b/arch/x86/entry/vdso/vdso-layout.lds.S
@@ -7,16 +7,6 @@
  * This script controls its layout.
  */
 
-#if defined(BUILD_VDSO64)
-# define SHDR_SIZE 64
-#elif defined(BUILD_VDSO32) || defined(BUILD_VDSOX32)
-# define SHDR_SIZE 40
-#else
-# error unknown VDSO target
-#endif
-
-#define NUM_FAKE_SHDRS 13
-
 SECTIONS
 {
/*
@@ -60,20 +50,8 @@ SECTIONS
*(.bss*)
*(.dynbss*)
*(.gnu.linkonce.b.*)
-
-   /*
-* Ideally this would live in a C file, but that won't
-* work cleanly for x32 until we start building the x32
-* C code using an x32 toolchain.
-*/
-   VDSO_FAKE_SECTION_TABLE_START = .;
-   . = . + NUM_FAKE_SHDRS * SHDR_SIZE;
-   VDSO_FAKE_SECTION_TABLE_END = .;
}   :text
 
-   .fake_shstrtab  : { *(.fake_shstrtab) } :text
-
-
.note   : { *(.note.*) }:text   :note
 
.eh_frame_hdr   : { *(.eh_frame_hdr) }  :text   :eh_frame_hdr
diff --git a/arch/x86/entry/vdso/vdso2c.c b/arch/x86/entry/vdso/vdso2c.c
index 4674f58581a1..8e470b018512 100644
--- a/arch/x86/entry/vdso/vdso2c.c
+++ b/arch/x86/entry/vdso/vdso2c.c
@@ -76,8 +76,6 @@ enum {
sym_hpet_page,
sym_pvclock_page,
sym_hvclock_page,
-   sym_VDSO_FAKE_SECTION_TABLE_START,
-   sym_VDSO_FAKE_SECTION_TABLE_END,
 };
 
 const int special_pages[] = {
@@ -98,12 +96,6 @@ struct vdso_sym required_syms[] = {
[sym_hpet_page] = {"hpet_page", true},
[sym_pvclock_page] = {"pvclock_page", true},
[sym_hvclock_page] = {"hvclock_page", true},
-   [sym_VDSO_FAKE_SECTION_TABLE_START] = {
-   "VDSO_FAKE_SECTION_TABLE_START", false
-   },
-   [sym_VDSO_FAKE_SECTION_TABLE_END] = {
-   "VDSO_FAKE_SECTION_TABLE_END", false
-   },
{"VDSO32_NOTE_MASK", true},
{"__kernel_vsyscall", true},
{"__kernel_sigreturn", true},


[tip:x86/cpu] x86/cpufeatures: Remove get_scattered_cpuid_leaf()

2018-11-05 Thread tip-bot for Sean Christopherson
Commit-ID:  43500e6f294d175602606c77bfb0d8cd4ea88b4f
Gitweb: https://git.kernel.org/tip/43500e6f294d175602606c77bfb0d8cd4ea88b4f
Author: Sean Christopherson 
AuthorDate: Mon, 5 Nov 2018 10:57:25 -0800
Committer:  Borislav Petkov 
CommitDate: Mon, 5 Nov 2018 20:54:20 +0100

x86/cpufeatures: Remove get_scattered_cpuid_leaf()

get_scattered_cpuid_leaf() was added[1] to help KVM rebuild hardware-
defined leafs that are rearranged by Linux to avoid bloating the
x86_capability array. Eventually, the last consumer of the function was
removed[2], but the function itself was kept, perhaps even intentionally
as a form of documentation.

Remove get_scattered_cpuid_leaf() as it is currently not used by KVM.
Furthermore, simply rebuilding the "real" leaf does not resolve all of
KVM's woes when it comes to exposing a scattered CPUID feature, i.e.
keeping the function as documentation may be counter-productive in some
scenarios, e.g. when KVM needs to do more than simply expose the leaf.

[1] 47bdf3378d62 ("x86/cpuid: Provide get_scattered_cpuid_leaf()")
[2] b7b27aa011a1 ("KVM/x86: Update the reverse_cpuid list to include 
CPUID_7_EDX")

Signed-off-by: Sean Christopherson 
Signed-off-by: Borislav Petkov 
CC: "H. Peter Anvin" 
CC: Ingo Molnar 
Cc: Paolo Bonzini 
Cc: Radim Krčmář 
CC: Thomas Gleixner 
CC: x86-ml 
Link: 
http://lkml.kernel.org/r/20181105185725.18679-1-sean.j.christopher...@intel.com
---
 arch/x86/kernel/cpu/cpu.h   |  3 ---
 arch/x86/kernel/cpu/scattered.c | 24 
 2 files changed, 27 deletions(-)

diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h
index da5446acc241..5eb946b9a9f3 100644
--- a/arch/x86/kernel/cpu/cpu.h
+++ b/arch/x86/kernel/cpu/cpu.h
@@ -49,9 +49,6 @@ extern void get_cpu_cap(struct cpuinfo_x86 *c);
 extern void get_cpu_address_sizes(struct cpuinfo_x86 *c);
 extern void cpu_detect_cache_sizes(struct cpuinfo_x86 *c);
 extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
-extern u32 get_scattered_cpuid_leaf(unsigned int level,
-   unsigned int sub_leaf,
-   enum cpuid_regs_idx reg);
 extern void init_intel_cacheinfo(struct cpuinfo_x86 *c);
 extern void init_amd_cacheinfo(struct cpuinfo_x86 *c);
 extern void init_hygon_cacheinfo(struct cpuinfo_x86 *c);
diff --git a/arch/x86/kernel/cpu/scattered.c b/arch/x86/kernel/cpu/scattered.c
index 772c219b6889..0631f5328b7f 100644
--- a/arch/x86/kernel/cpu/scattered.c
+++ b/arch/x86/kernel/cpu/scattered.c
@@ -56,27 +56,3 @@ void init_scattered_cpuid_features(struct cpuinfo_x86 *c)
set_cpu_cap(c, cb->feature);
}
 }
-
-u32 get_scattered_cpuid_leaf(unsigned int level, unsigned int sub_leaf,
-enum cpuid_regs_idx reg)
-{
-   const struct cpuid_bit *cb;
-   u32 cpuid_val = 0;
-
-   for (cb = cpuid_bits; cb->feature; cb++) {
-
-   if (level > cb->level)
-   continue;
-
-   if (level < cb->level)
-   break;
-
-   if (reg == cb->reg && sub_leaf == cb->sub_leaf) {
-   if (cpu_has(&boot_cpu_data, cb->feature))
-   cpuid_val |= BIT(cb->bit);
-   }
-   }
-
-   return cpuid_val;
-}
-EXPORT_SYMBOL_GPL(get_scattered_cpuid_leaf);