mirror of
https://github.com/torvalds/linux.git
synced 2026-01-25 15:03:52 +08:00
Merge branch 'x86/asm' into x86/core, to pick up dependent commits
Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
@@ -180,10 +180,6 @@ Dump-capture kernel config options (Arch Dependent, i386 and x86_64)
|
||||
1) On i386, enable high memory support under "Processor type and
|
||||
features"::
|
||||
|
||||
CONFIG_HIGHMEM64G=y
|
||||
|
||||
or::
|
||||
|
||||
CONFIG_HIGHMEM4G
|
||||
|
||||
2) With CONFIG_SMP=y, usually nr_cpus=1 need specified on the kernel
|
||||
|
||||
@@ -416,10 +416,6 @@
|
||||
Format: { quiet (default) | verbose | debug }
|
||||
Change the amount of debugging information output
|
||||
when initialising the APIC and IO-APIC components.
|
||||
For X86-32, this can also be used to specify an APIC
|
||||
driver name.
|
||||
Format: apic=driver_name
|
||||
Examples: apic=bigsmp
|
||||
|
||||
apic_extnmi= [APIC,X86,EARLY] External NMI delivery setting
|
||||
Format: { bsp (default) | all | none }
|
||||
@@ -7672,13 +7668,6 @@
|
||||
16 - SIGBUS faults
|
||||
Example: user_debug=31
|
||||
|
||||
userpte=
|
||||
[X86,EARLY] Flags controlling user PTE allocations.
|
||||
|
||||
nohigh = do not allocate PTE pages in
|
||||
HIGHMEM regardless of setting
|
||||
of CONFIG_HIGHPTE.
|
||||
|
||||
vdso= [X86,SH,SPARC]
|
||||
On X86_32, this is an alias for vdso32=. Otherwise:
|
||||
|
||||
|
||||
@@ -20,11 +20,7 @@ It has several drawbacks, though:
|
||||
features (wheel, extra buttons, touchpad mode) of the real PS/2 mouse may
|
||||
not be available.
|
||||
|
||||
2) If CONFIG_HIGHMEM64G is enabled, the PS/2 mouse emulation can cause
|
||||
system crashes, because the SMM BIOS is not expecting to be in PAE mode.
|
||||
The Intel E7505 is a typical machine where this happens.
|
||||
|
||||
3) If AMD64 64-bit mode is enabled, again system crashes often happen,
|
||||
2) If AMD64 64-bit mode is enabled, again system crashes often happen,
|
||||
because the SMM BIOS isn't expecting the CPU to be in 64-bit mode. The
|
||||
BIOS manufacturers only test with Windows, and Windows doesn't do 64-bit
|
||||
yet.
|
||||
@@ -38,11 +34,6 @@ Problem 1)
|
||||
compiled-in, too.
|
||||
|
||||
Problem 2)
|
||||
can currently only be solved by either disabling HIGHMEM64G
|
||||
in the kernel config or USB Legacy support in the BIOS. A BIOS update
|
||||
could help, but so far no such update exists.
|
||||
|
||||
Problem 3)
|
||||
is usually fixed by a BIOS update. Check the board
|
||||
manufacturers web site. If an update is not available, disable USB
|
||||
Legacy support in the BIOS. If this alone doesn't help, try also adding
|
||||
|
||||
@@ -381,7 +381,7 @@ void __iomem *ioremap_wc(resource_size_t res_cookie, size_t size);
|
||||
void iounmap(volatile void __iomem *io_addr);
|
||||
#define iounmap iounmap
|
||||
|
||||
void *arch_memremap_wb(phys_addr_t phys_addr, size_t size);
|
||||
void *arch_memremap_wb(phys_addr_t phys_addr, size_t size, unsigned long flags);
|
||||
#define arch_memremap_wb arch_memremap_wb
|
||||
|
||||
/*
|
||||
|
||||
@@ -436,7 +436,7 @@ void __arm_iomem_set_ro(void __iomem *ptr, size_t size)
|
||||
set_memory_ro((unsigned long)ptr, PAGE_ALIGN(size) / PAGE_SIZE);
|
||||
}
|
||||
|
||||
void *arch_memremap_wb(phys_addr_t phys_addr, size_t size)
|
||||
void *arch_memremap_wb(phys_addr_t phys_addr, size_t size, unsigned long flags)
|
||||
{
|
||||
return (__force void *)arch_ioremap_caller(phys_addr, size,
|
||||
MT_MEMORY_RW,
|
||||
|
||||
@@ -248,7 +248,7 @@ void __iomem *pci_remap_cfgspace(resource_size_t res_cookie, size_t size)
|
||||
EXPORT_SYMBOL_GPL(pci_remap_cfgspace);
|
||||
#endif
|
||||
|
||||
void *arch_memremap_wb(phys_addr_t phys_addr, size_t size)
|
||||
void *arch_memremap_wb(phys_addr_t phys_addr, size_t size, unsigned long flags)
|
||||
{
|
||||
return (void *)phys_addr;
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ __io_writes_outs(outs, u64, q, __io_pbr(), __io_paw())
|
||||
#include <asm-generic/io.h>
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
#define arch_memremap_wb(addr, size) \
|
||||
#define arch_memremap_wb(addr, size, flags) \
|
||||
((__force void *)ioremap_prot((addr), (size), _PAGE_KERNEL))
|
||||
#endif
|
||||
|
||||
|
||||
191
arch/x86/Kconfig
191
arch/x86/Kconfig
@@ -133,7 +133,7 @@ config X86
|
||||
select ARCH_SUPPORTS_AUTOFDO_CLANG
|
||||
select ARCH_SUPPORTS_PROPELLER_CLANG if X86_64
|
||||
select ARCH_USE_BUILTIN_BSWAP
|
||||
select ARCH_USE_CMPXCHG_LOCKREF if X86_CMPXCHG64
|
||||
select ARCH_USE_CMPXCHG_LOCKREF if X86_CX8
|
||||
select ARCH_USE_MEMTEST
|
||||
select ARCH_USE_QUEUED_RWLOCKS
|
||||
select ARCH_USE_QUEUED_SPINLOCKS
|
||||
@@ -233,7 +233,7 @@ config X86
|
||||
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI if X86_64
|
||||
select HAVE_EBPF_JIT
|
||||
select HAVE_EFFICIENT_UNALIGNED_ACCESS
|
||||
select HAVE_EISA
|
||||
select HAVE_EISA if X86_32
|
||||
select HAVE_EXIT_THREAD
|
||||
select HAVE_GUP_FAST
|
||||
select HAVE_FENTRY if X86_64 || DYNAMIC_FTRACE
|
||||
@@ -278,7 +278,7 @@ config X86
|
||||
select HAVE_PCI
|
||||
select HAVE_PERF_REGS
|
||||
select HAVE_PERF_USER_STACK_DUMP
|
||||
select MMU_GATHER_RCU_TABLE_FREE if PARAVIRT
|
||||
select MMU_GATHER_RCU_TABLE_FREE
|
||||
select MMU_GATHER_MERGE_VMAS
|
||||
select HAVE_POSIX_CPU_TIMERS_TASK_WORK
|
||||
select HAVE_REGS_AND_STACK_ACCESS_API
|
||||
@@ -286,7 +286,7 @@ config X86
|
||||
select HAVE_FUNCTION_ARG_ACCESS_API
|
||||
select HAVE_SETUP_PER_CPU_AREA
|
||||
select HAVE_SOFTIRQ_ON_OWN_STACK
|
||||
select HAVE_STACKPROTECTOR if CC_HAS_SANE_STACKPROTECTOR
|
||||
select HAVE_STACKPROTECTOR
|
||||
select HAVE_STACK_VALIDATION if HAVE_OBJTOOL
|
||||
select HAVE_STATIC_CALL
|
||||
select HAVE_STATIC_CALL_INLINE if HAVE_OBJTOOL
|
||||
@@ -427,15 +427,6 @@ config PGTABLE_LEVELS
|
||||
default 3 if X86_PAE
|
||||
default 2
|
||||
|
||||
config CC_HAS_SANE_STACKPROTECTOR
|
||||
bool
|
||||
default $(success,$(srctree)/scripts/gcc-x86_64-has-stack-protector.sh $(CC) $(CLANG_FLAGS)) if 64BIT
|
||||
default $(success,$(srctree)/scripts/gcc-x86_32-has-stack-protector.sh $(CC) $(CLANG_FLAGS))
|
||||
help
|
||||
We have to make sure stack protector is unconditionally disabled if
|
||||
the compiler produces broken code or if it does not let us control
|
||||
the segment on 32-bit kernels.
|
||||
|
||||
menu "Processor type and features"
|
||||
|
||||
config SMP
|
||||
@@ -531,12 +522,6 @@ config X86_FRED
|
||||
ring transitions and exception/interrupt handling if the
|
||||
system supports it.
|
||||
|
||||
config X86_BIGSMP
|
||||
bool "Support for big SMP systems with more than 8 CPUs"
|
||||
depends on SMP && X86_32
|
||||
help
|
||||
This option is needed for the systems that have more than 8 CPUs.
|
||||
|
||||
config X86_EXTENDED_PLATFORM
|
||||
bool "Support for extended (non-PC) x86 platforms"
|
||||
default y
|
||||
@@ -554,13 +539,12 @@ config X86_EXTENDED_PLATFORM
|
||||
AMD Elan
|
||||
RDC R-321x SoC
|
||||
SGI 320/540 (Visual Workstation)
|
||||
STA2X11-based (e.g. Northville)
|
||||
Moorestown MID devices
|
||||
|
||||
64-bit platforms (CONFIG_64BIT=y):
|
||||
Numascale NumaChip
|
||||
ScaleMP vSMP
|
||||
SGI Ultraviolet
|
||||
Merrifield/Moorefield MID devices
|
||||
|
||||
If you have one of these systems, or if you want to build a
|
||||
generic distribution kernel, say Y here - otherwise say N.
|
||||
@@ -605,8 +589,31 @@ config X86_UV
|
||||
This option is needed in order to support SGI Ultraviolet systems.
|
||||
If you don't have one of these, you should say N here.
|
||||
|
||||
# Following is an alphabetically sorted list of 32 bit extended platforms
|
||||
# Please maintain the alphabetic order if and when there are additions
|
||||
config X86_INTEL_MID
|
||||
bool "Intel Z34xx/Z35xx MID platform support"
|
||||
depends on X86_EXTENDED_PLATFORM
|
||||
depends on X86_PLATFORM_DEVICES
|
||||
depends on PCI
|
||||
depends on X86_64 || (EXPERT && PCI_GOANY)
|
||||
depends on X86_IO_APIC
|
||||
select I2C
|
||||
select DW_APB_TIMER
|
||||
select INTEL_SCU_PCI
|
||||
help
|
||||
Select to build a kernel capable of supporting 64-bit Intel MID
|
||||
(Mobile Internet Device) platform systems which do not have
|
||||
the PCI legacy interfaces.
|
||||
|
||||
The only supported devices are the 22nm Merrified (Z34xx)
|
||||
and Moorefield (Z35xx) SoC used in the Intel Edison board and
|
||||
a small number of Android devices such as the Asus Zenfone 2,
|
||||
Asus FonePad 8 and Dell Venue 7.
|
||||
|
||||
If you are building for a PC class system or non-MID tablet
|
||||
SoCs like Bay Trail (Z36xx/Z37xx), say N here.
|
||||
|
||||
Intel MID platforms are based on an Intel processor and chipset which
|
||||
consume less power than most of the x86 derivatives.
|
||||
|
||||
config X86_GOLDFISH
|
||||
bool "Goldfish (Virtual Platform)"
|
||||
@@ -616,6 +623,9 @@ config X86_GOLDFISH
|
||||
for Android development. Unless you are building for the Android
|
||||
Goldfish emulator say N here.
|
||||
|
||||
# Following is an alphabetically sorted list of 32 bit extended platforms
|
||||
# Please maintain the alphabetic order if and when there are additions
|
||||
|
||||
config X86_INTEL_CE
|
||||
bool "CE4100 TV platform"
|
||||
depends on PCI
|
||||
@@ -631,24 +641,6 @@ config X86_INTEL_CE
|
||||
This option compiles in support for the CE4100 SOC for settop
|
||||
boxes and media devices.
|
||||
|
||||
config X86_INTEL_MID
|
||||
bool "Intel MID platform support"
|
||||
depends on X86_EXTENDED_PLATFORM
|
||||
depends on X86_PLATFORM_DEVICES
|
||||
depends on PCI
|
||||
depends on X86_64 || (PCI_GOANY && X86_32)
|
||||
depends on X86_IO_APIC
|
||||
select I2C
|
||||
select DW_APB_TIMER
|
||||
select INTEL_SCU_PCI
|
||||
help
|
||||
Select to build a kernel capable of supporting Intel MID (Mobile
|
||||
Internet Device) platform systems which do not have the PCI legacy
|
||||
interfaces. If you are building for a PC class system say N here.
|
||||
|
||||
Intel MID platforms are based on an Intel processor and chipset which
|
||||
consume less power than most of the x86 derivatives.
|
||||
|
||||
config X86_INTEL_QUARK
|
||||
bool "Intel Quark platform support"
|
||||
depends on X86_32
|
||||
@@ -730,18 +722,6 @@ config X86_RDC321X
|
||||
as R-8610-(G).
|
||||
If you don't have one of these chips, you should say N here.
|
||||
|
||||
config X86_32_NON_STANDARD
|
||||
bool "Support non-standard 32-bit SMP architectures"
|
||||
depends on X86_32 && SMP
|
||||
depends on X86_EXTENDED_PLATFORM
|
||||
help
|
||||
This option compiles in the bigsmp and STA2X11 default
|
||||
subarchitectures. It is intended for a generic binary
|
||||
kernel. If you select them all, kernel will probe it one by
|
||||
one and will fallback to default.
|
||||
|
||||
# Alphabetically sorted list of Non standard 32 bit platforms
|
||||
|
||||
config X86_SUPPORTS_MEMORY_FAILURE
|
||||
def_bool y
|
||||
# MCE code calls memory_failure():
|
||||
@@ -751,19 +731,6 @@ config X86_SUPPORTS_MEMORY_FAILURE
|
||||
depends on X86_64 || !SPARSEMEM
|
||||
select ARCH_SUPPORTS_MEMORY_FAILURE
|
||||
|
||||
config STA2X11
|
||||
bool "STA2X11 Companion Chip Support"
|
||||
depends on X86_32_NON_STANDARD && PCI
|
||||
select SWIOTLB
|
||||
select MFD_STA2X11
|
||||
select GPIOLIB
|
||||
help
|
||||
This adds support for boards based on the STA2X11 IO-Hub,
|
||||
a.k.a. "ConneXt". The chip is used in place of the standard
|
||||
PC chipset, so all "standard" peripherals are missing. If this
|
||||
option is selected the kernel will still be able to boot on
|
||||
standard PC machines.
|
||||
|
||||
config X86_32_IRIS
|
||||
tristate "Eurobraille/Iris poweroff module"
|
||||
depends on X86_32
|
||||
@@ -1013,8 +980,7 @@ config NR_CPUS_RANGE_BEGIN
|
||||
config NR_CPUS_RANGE_END
|
||||
int
|
||||
depends on X86_32
|
||||
default 64 if SMP && X86_BIGSMP
|
||||
default 8 if SMP && !X86_BIGSMP
|
||||
default 8 if SMP
|
||||
default 1 if !SMP
|
||||
|
||||
config NR_CPUS_RANGE_END
|
||||
@@ -1027,7 +993,6 @@ config NR_CPUS_RANGE_END
|
||||
config NR_CPUS_DEFAULT
|
||||
int
|
||||
depends on X86_32
|
||||
default 32 if X86_BIGSMP
|
||||
default 8 if SMP
|
||||
default 1 if !SMP
|
||||
|
||||
@@ -1103,7 +1068,7 @@ config UP_LATE_INIT
|
||||
config X86_UP_APIC
|
||||
bool "Local APIC support on uniprocessors" if !PCI_MSI
|
||||
default PCI_MSI
|
||||
depends on X86_32 && !SMP && !X86_32_NON_STANDARD
|
||||
depends on X86_32 && !SMP
|
||||
help
|
||||
A local APIC (Advanced Programmable Interrupt Controller) is an
|
||||
integrated interrupt controller in the CPU. If you have a single-CPU
|
||||
@@ -1128,7 +1093,7 @@ config X86_UP_IOAPIC
|
||||
|
||||
config X86_LOCAL_APIC
|
||||
def_bool y
|
||||
depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_APIC || PCI_MSI
|
||||
depends on X86_64 || SMP || X86_UP_APIC || PCI_MSI
|
||||
select IRQ_DOMAIN_HIERARCHY
|
||||
|
||||
config ACPI_MADT_WAKEUP
|
||||
@@ -1396,15 +1361,11 @@ config X86_CPUID
|
||||
with major 203 and minors 0 to 31 for /dev/cpu/0/cpuid to
|
||||
/dev/cpu/31/cpuid.
|
||||
|
||||
choice
|
||||
prompt "High Memory Support"
|
||||
default HIGHMEM4G
|
||||
config HIGHMEM4G
|
||||
bool "High Memory Support"
|
||||
depends on X86_32
|
||||
|
||||
config NOHIGHMEM
|
||||
bool "off"
|
||||
help
|
||||
Linux can use up to 64 Gigabytes of physical memory on x86 systems.
|
||||
Linux can use up to 4 Gigabytes of physical memory on x86 systems.
|
||||
However, the address space of 32-bit x86 processors is only 4
|
||||
Gigabytes large. That means that, if you have a large amount of
|
||||
physical memory, not all of it can be "permanently mapped" by the
|
||||
@@ -1420,38 +1381,9 @@ config NOHIGHMEM
|
||||
possible.
|
||||
|
||||
If the machine has between 1 and 4 Gigabytes physical RAM, then
|
||||
answer "4GB" here.
|
||||
answer "Y" here.
|
||||
|
||||
If more than 4 Gigabytes is used then answer "64GB" here. This
|
||||
selection turns Intel PAE (Physical Address Extension) mode on.
|
||||
PAE implements 3-level paging on IA32 processors. PAE is fully
|
||||
supported by Linux, PAE mode is implemented on all recent Intel
|
||||
processors (Pentium Pro and better). NOTE: If you say "64GB" here,
|
||||
then the kernel will not boot on CPUs that don't support PAE!
|
||||
|
||||
The actual amount of total physical memory will either be
|
||||
auto detected or can be forced by using a kernel command line option
|
||||
such as "mem=256M". (Try "man bootparam" or see the documentation of
|
||||
your boot loader (lilo or loadlin) about how to pass options to the
|
||||
kernel at boot time.)
|
||||
|
||||
If unsure, say "off".
|
||||
|
||||
config HIGHMEM4G
|
||||
bool "4GB"
|
||||
help
|
||||
Select this if you have a 32-bit processor and between 1 and 4
|
||||
gigabytes of physical RAM.
|
||||
|
||||
config HIGHMEM64G
|
||||
bool "64GB"
|
||||
depends on X86_HAVE_PAE
|
||||
select X86_PAE
|
||||
help
|
||||
Select this if you have a 32-bit processor and more than 4
|
||||
gigabytes of physical RAM.
|
||||
|
||||
endchoice
|
||||
If unsure, say N.
|
||||
|
||||
choice
|
||||
prompt "Memory split" if EXPERT
|
||||
@@ -1497,14 +1429,12 @@ config PAGE_OFFSET
|
||||
depends on X86_32
|
||||
|
||||
config HIGHMEM
|
||||
def_bool y
|
||||
depends on X86_32 && (HIGHMEM64G || HIGHMEM4G)
|
||||
def_bool HIGHMEM4G
|
||||
|
||||
config X86_PAE
|
||||
bool "PAE (Physical Address Extension) Support"
|
||||
depends on X86_32 && X86_HAVE_PAE
|
||||
select PHYS_ADDR_T_64BIT
|
||||
select SWIOTLB
|
||||
help
|
||||
PAE is required for NX support, and furthermore enables
|
||||
larger swapspace support for non-overcommit purposes. It
|
||||
@@ -1574,8 +1504,7 @@ config AMD_MEM_ENCRYPT
|
||||
config NUMA
|
||||
bool "NUMA Memory Allocation and Scheduler Support"
|
||||
depends on SMP
|
||||
depends on X86_64 || (X86_32 && HIGHMEM64G && X86_BIGSMP)
|
||||
default y if X86_BIGSMP
|
||||
depends on X86_64
|
||||
select USE_PERCPU_NUMA_NODE_ID
|
||||
select OF_NUMA if OF
|
||||
help
|
||||
@@ -1588,9 +1517,6 @@ config NUMA
|
||||
For 64-bit this is recommended if the system is Intel Core i7
|
||||
(or later), AMD Opteron, or EM64T NUMA.
|
||||
|
||||
For 32-bit this is only needed if you boot a 32-bit
|
||||
kernel on a 64-bit NUMA platform.
|
||||
|
||||
Otherwise, you should say N.
|
||||
|
||||
config AMD_NUMA
|
||||
@@ -1629,7 +1555,7 @@ config ARCH_FLATMEM_ENABLE
|
||||
|
||||
config ARCH_SPARSEMEM_ENABLE
|
||||
def_bool y
|
||||
depends on X86_64 || NUMA || X86_32 || X86_32_NON_STANDARD
|
||||
depends on X86_64 || NUMA || X86_32
|
||||
select SPARSEMEM_STATIC if X86_32
|
||||
select SPARSEMEM_VMEMMAP_ENABLE if X86_64
|
||||
|
||||
@@ -1675,15 +1601,6 @@ config X86_PMEM_LEGACY
|
||||
|
||||
Say Y if unsure.
|
||||
|
||||
config HIGHPTE
|
||||
bool "Allocate 3rd-level pagetables from highmem"
|
||||
depends on HIGHMEM
|
||||
help
|
||||
The VM uses one page table entry for each page of physical memory.
|
||||
For systems with a lot of RAM, this can be wasteful of precious
|
||||
low memory. Setting this option will put user-space page table
|
||||
entries in high memory.
|
||||
|
||||
config X86_CHECK_BIOS_CORRUPTION
|
||||
bool "Check for low memory corruption"
|
||||
help
|
||||
@@ -2451,18 +2368,20 @@ config CC_HAS_NAMED_AS
|
||||
def_bool $(success,echo 'int __seg_fs fs; int __seg_gs gs;' | $(CC) -x c - -S -o /dev/null)
|
||||
depends on CC_IS_GCC
|
||||
|
||||
#
|
||||
# -fsanitize=kernel-address (KASAN) and -fsanitize=thread (KCSAN)
|
||||
# are incompatible with named address spaces with GCC < 13.3
|
||||
# (see GCC PR sanitizer/111736 and also PR sanitizer/115172).
|
||||
#
|
||||
|
||||
config CC_HAS_NAMED_AS_FIXED_SANITIZERS
|
||||
def_bool CC_IS_GCC && GCC_VERSION >= 130300
|
||||
def_bool y
|
||||
depends on !(KASAN || KCSAN) || GCC_VERSION >= 130300
|
||||
depends on !(UBSAN_BOOL && KASAN) || GCC_VERSION >= 140200
|
||||
|
||||
config USE_X86_SEG_SUPPORT
|
||||
def_bool y
|
||||
depends on CC_HAS_NAMED_AS
|
||||
#
|
||||
# -fsanitize=kernel-address (KASAN) and -fsanitize=thread
|
||||
# (KCSAN) are incompatible with named address spaces with
|
||||
# GCC < 13.3 - see GCC PR sanitizer/111736.
|
||||
#
|
||||
depends on !(KASAN || KCSAN) || CC_HAS_NAMED_AS_FIXED_SANITIZERS
|
||||
def_bool CC_HAS_NAMED_AS
|
||||
depends on CC_HAS_NAMED_AS_FIXED_SANITIZERS
|
||||
|
||||
config CC_HAS_SLS
|
||||
def_bool $(cc-option,-mharden-sls=all)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# Put here option for CPU selection and depending optimization
|
||||
choice
|
||||
prompt "Processor family"
|
||||
default M686 if X86_32
|
||||
default GENERIC_CPU if X86_64
|
||||
prompt "x86-32 Processor family"
|
||||
depends on X86_32
|
||||
default M686
|
||||
help
|
||||
This is the processor type of your CPU. This information is
|
||||
used for optimizing purposes. In order to compile a kernel
|
||||
@@ -31,7 +31,6 @@ choice
|
||||
- "Pentium-4" for the Intel Pentium 4 or P4-based Celeron.
|
||||
- "K6" for the AMD K6, K6-II and K6-III (aka K6-3D).
|
||||
- "Athlon" for the AMD K7 family (Athlon/Duron/Thunderbird).
|
||||
- "Opteron/Athlon64/Hammer/K8" for all K8 and newer AMD CPUs.
|
||||
- "Crusoe" for the Transmeta Crusoe series.
|
||||
- "Efficeon" for the Transmeta Efficeon series.
|
||||
- "Winchip-C6" for original IDT Winchip.
|
||||
@@ -42,13 +41,10 @@ choice
|
||||
- "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3.
|
||||
- "VIA C3-2" for VIA C3-2 "Nehemiah" (model 9 and above).
|
||||
- "VIA C7" for VIA C7.
|
||||
- "Intel P4" for the Pentium 4/Netburst microarchitecture.
|
||||
- "Core 2/newer Xeon" for all core2 and newer Intel CPUs.
|
||||
- "Intel Atom" for the Atom-microarchitecture CPUs.
|
||||
- "Generic-x86-64" for a kernel which runs on any x86-64 CPU.
|
||||
|
||||
See each option's help text for additional details. If you don't know
|
||||
what to do, choose "486".
|
||||
what to do, choose "Pentium-Pro".
|
||||
|
||||
config M486SX
|
||||
bool "486SX"
|
||||
@@ -114,11 +110,11 @@ config MPENTIUMIII
|
||||
extensions.
|
||||
|
||||
config MPENTIUMM
|
||||
bool "Pentium M"
|
||||
bool "Pentium M/Pentium Dual Core/Core Solo/Core Duo"
|
||||
depends on X86_32
|
||||
help
|
||||
Select this for Intel Pentium M (not Pentium-4 M)
|
||||
notebook chips.
|
||||
"Merom" Core Solo/Duo notebook chips
|
||||
|
||||
config MPENTIUM4
|
||||
bool "Pentium-4/Celeron(P4-based)/Pentium-4 M/older Xeon"
|
||||
@@ -139,22 +135,10 @@ config MPENTIUM4
|
||||
-Mobile Pentium 4
|
||||
-Mobile Pentium 4 M
|
||||
-Extreme Edition (Gallatin)
|
||||
-Prescott
|
||||
-Prescott 2M
|
||||
-Cedar Mill
|
||||
-Presler
|
||||
-Smithfiled
|
||||
Xeons (Intel Xeon, Xeon MP, Xeon LV, Xeon MV) corename:
|
||||
-Foster
|
||||
-Prestonia
|
||||
-Gallatin
|
||||
-Nocona
|
||||
-Irwindale
|
||||
-Cranford
|
||||
-Potomac
|
||||
-Paxville
|
||||
-Dempsey
|
||||
|
||||
|
||||
config MK6
|
||||
bool "K6/K6-II/K6-III"
|
||||
@@ -172,13 +156,6 @@ config MK7
|
||||
some extended instructions, and passes appropriate optimization
|
||||
flags to GCC.
|
||||
|
||||
config MK8
|
||||
bool "Opteron/Athlon64/Hammer/K8"
|
||||
help
|
||||
Select this for an AMD Opteron or Athlon64 Hammer-family processor.
|
||||
Enables use of some extended instructions, and passes appropriate
|
||||
optimization flags to GCC.
|
||||
|
||||
config MCRUSOE
|
||||
bool "Crusoe"
|
||||
depends on X86_32
|
||||
@@ -258,42 +235,14 @@ config MVIAC7
|
||||
Select this for a VIA C7. Selecting this uses the correct cache
|
||||
shift and tells gcc to treat the CPU as a 686.
|
||||
|
||||
config MPSC
|
||||
bool "Intel P4 / older Netburst based Xeon"
|
||||
depends on X86_64
|
||||
help
|
||||
Optimize for Intel Pentium 4, Pentium D and older Nocona/Dempsey
|
||||
Xeon CPUs with Intel 64bit which is compatible with x86-64.
|
||||
Note that the latest Xeons (Xeon 51xx and 53xx) are not based on the
|
||||
Netburst core and shouldn't use this option. You can distinguish them
|
||||
using the cpu family field
|
||||
in /proc/cpuinfo. Family 15 is an older Xeon, Family 6 a newer one.
|
||||
|
||||
config MCORE2
|
||||
bool "Core 2/newer Xeon"
|
||||
help
|
||||
|
||||
Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and
|
||||
53xx) CPUs. You can distinguish newer from older Xeons by the CPU
|
||||
family in /proc/cpuinfo. Newer ones have 6 and older ones 15
|
||||
(not a typo)
|
||||
|
||||
config MATOM
|
||||
bool "Intel Atom"
|
||||
help
|
||||
|
||||
Select this for the Intel Atom platform. Intel Atom CPUs have an
|
||||
in-order pipelining architecture and thus can benefit from
|
||||
accordingly optimized code. Use a recent GCC with specific Atom
|
||||
support in order to fully benefit from selecting this option.
|
||||
|
||||
config GENERIC_CPU
|
||||
bool "Generic-x86-64"
|
||||
depends on X86_64
|
||||
help
|
||||
Generic x86-64 CPU.
|
||||
Run equally well on all x86-64 CPUs.
|
||||
|
||||
endchoice
|
||||
|
||||
config X86_GENERIC
|
||||
@@ -317,8 +266,8 @@ config X86_INTERNODE_CACHE_SHIFT
|
||||
|
||||
config X86_L1_CACHE_SHIFT
|
||||
int
|
||||
default "7" if MPENTIUM4 || MPSC
|
||||
default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU
|
||||
default "7" if MPENTIUM4
|
||||
default "6" if MK7 || MPENTIUMM || MATOM || MVIAC7 || X86_GENERIC || X86_64
|
||||
default "4" if MELAN || M486SX || M486 || MGEODEGX1
|
||||
default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
|
||||
|
||||
@@ -336,51 +285,35 @@ config X86_ALIGNMENT_16
|
||||
|
||||
config X86_INTEL_USERCOPY
|
||||
def_bool y
|
||||
depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2
|
||||
depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK7 || MEFFICEON
|
||||
|
||||
config X86_USE_PPRO_CHECKSUM
|
||||
def_bool y
|
||||
depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX || MCORE2 || MATOM
|
||||
|
||||
#
|
||||
# P6_NOPs are a relatively minor optimization that require a family >=
|
||||
# 6 processor, except that it is broken on certain VIA chips.
|
||||
# Furthermore, AMD chips prefer a totally different sequence of NOPs
|
||||
# (which work on all CPUs). In addition, it looks like Virtual PC
|
||||
# does not understand them.
|
||||
#
|
||||
# As a result, disallow these if we're not compiling for X86_64 (these
|
||||
# NOPs do work on all x86-64 capable chips); the list of processors in
|
||||
# the right-hand clause are the cores that benefit from this optimization.
|
||||
#
|
||||
config X86_P6_NOP
|
||||
def_bool y
|
||||
depends on X86_64
|
||||
depends on (MCORE2 || MPENTIUM4 || MPSC)
|
||||
depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX || MATOM
|
||||
|
||||
config X86_TSC
|
||||
def_bool y
|
||||
depends on (MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM) || X86_64
|
||||
depends on (MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MATOM) || X86_64
|
||||
|
||||
config X86_HAVE_PAE
|
||||
def_bool y
|
||||
depends on MCRUSOE || MEFFICEON || MCYRIXIII || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC7 || MCORE2 || MATOM || X86_64
|
||||
depends on MCRUSOE || MEFFICEON || MCYRIXIII || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC7 || MATOM || X86_64
|
||||
|
||||
config X86_CMPXCHG64
|
||||
config X86_CX8
|
||||
def_bool y
|
||||
depends on X86_HAVE_PAE || M586TSC || M586MMX || MK6 || MK7
|
||||
depends on X86_HAVE_PAE || M586TSC || M586MMX || MK6 || MK7 || MGEODEGX1 || MGEODE_LX
|
||||
|
||||
# this should be set for all -march=.. options where the compiler
|
||||
# generates cmov.
|
||||
config X86_CMOV
|
||||
def_bool y
|
||||
depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX)
|
||||
depends on (MK7 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || MATOM || MGEODE_LX || X86_64)
|
||||
|
||||
config X86_MINIMUM_CPU_FAMILY
|
||||
int
|
||||
default "64" if X86_64
|
||||
default "6" if X86_32 && (MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MEFFICEON || MATOM || MCORE2 || MK7 || MK8)
|
||||
default "5" if X86_32 && X86_CMPXCHG64
|
||||
default "6" if X86_32 && (MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MEFFICEON || MATOM || MK7)
|
||||
default "5" if X86_32 && X86_CX8
|
||||
default "4"
|
||||
|
||||
config X86_DEBUGCTLMSR
|
||||
|
||||
@@ -140,14 +140,7 @@ ifeq ($(CONFIG_X86_32),y)
|
||||
# temporary until string.h is fixed
|
||||
KBUILD_CFLAGS += -ffreestanding
|
||||
|
||||
ifeq ($(CONFIG_STACKPROTECTOR),y)
|
||||
ifeq ($(CONFIG_SMP),y)
|
||||
KBUILD_CFLAGS += -mstack-protector-guard-reg=fs \
|
||||
-mstack-protector-guard-symbol=__ref_stack_chk_guard
|
||||
else
|
||||
KBUILD_CFLAGS += -mstack-protector-guard=global
|
||||
endif
|
||||
endif
|
||||
percpu_seg := fs
|
||||
else
|
||||
BITS := 64
|
||||
UTS_MACHINE := x86_64
|
||||
@@ -178,25 +171,24 @@ else
|
||||
# Use -mskip-rax-setup if supported.
|
||||
KBUILD_CFLAGS += $(call cc-option,-mskip-rax-setup)
|
||||
|
||||
# FIXME - should be integrated in Makefile.cpu (Makefile_32.cpu)
|
||||
cflags-$(CONFIG_MK8) += -march=k8
|
||||
cflags-$(CONFIG_MPSC) += -march=nocona
|
||||
cflags-$(CONFIG_MCORE2) += -march=core2
|
||||
cflags-$(CONFIG_MATOM) += -march=atom
|
||||
cflags-$(CONFIG_GENERIC_CPU) += -mtune=generic
|
||||
KBUILD_CFLAGS += $(cflags-y)
|
||||
|
||||
rustflags-$(CONFIG_MK8) += -Ctarget-cpu=k8
|
||||
rustflags-$(CONFIG_MPSC) += -Ctarget-cpu=nocona
|
||||
rustflags-$(CONFIG_MCORE2) += -Ctarget-cpu=core2
|
||||
rustflags-$(CONFIG_MATOM) += -Ctarget-cpu=atom
|
||||
rustflags-$(CONFIG_GENERIC_CPU) += -Ztune-cpu=generic
|
||||
KBUILD_RUSTFLAGS += $(rustflags-y)
|
||||
KBUILD_CFLAGS += -march=x86-64 -mtune=generic
|
||||
KBUILD_RUSTFLAGS += -Ctarget-cpu=x86-64 -Ztune-cpu=generic
|
||||
|
||||
KBUILD_CFLAGS += -mno-red-zone
|
||||
KBUILD_CFLAGS += -mcmodel=kernel
|
||||
KBUILD_RUSTFLAGS += -Cno-redzone=y
|
||||
KBUILD_RUSTFLAGS += -Ccode-model=kernel
|
||||
|
||||
percpu_seg := gs
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_STACKPROTECTOR),y)
|
||||
ifeq ($(CONFIG_SMP),y)
|
||||
KBUILD_CFLAGS += -mstack-protector-guard-reg=$(percpu_seg)
|
||||
KBUILD_CFLAGS += -mstack-protector-guard-symbol=__ref_stack_chk_guard
|
||||
else
|
||||
KBUILD_CFLAGS += -mstack-protector-guard=global
|
||||
endif
|
||||
endif
|
||||
|
||||
#
|
||||
|
||||
@@ -24,7 +24,6 @@ cflags-$(CONFIG_MK6) += -march=k6
|
||||
# Please note, that patches that add -march=athlon-xp and friends are pointless.
|
||||
# They make zero difference whatsosever to performance at this time.
|
||||
cflags-$(CONFIG_MK7) += -march=athlon
|
||||
cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8,-march=athlon)
|
||||
cflags-$(CONFIG_MCRUSOE) += -march=i686 $(align)
|
||||
cflags-$(CONFIG_MEFFICEON) += -march=i686 $(call tune,pentium3) $(align)
|
||||
cflags-$(CONFIG_MWINCHIPC6) += $(call cc-option,-march=winchip-c6,-march=i586)
|
||||
@@ -32,9 +31,7 @@ cflags-$(CONFIG_MWINCHIP3D) += $(call cc-option,-march=winchip2,-march=i586)
|
||||
cflags-$(CONFIG_MCYRIXIII) += $(call cc-option,-march=c3,-march=i486) $(align)
|
||||
cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686)
|
||||
cflags-$(CONFIG_MVIAC7) += -march=i686
|
||||
cflags-$(CONFIG_MCORE2) += -march=i686 $(call tune,core2)
|
||||
cflags-$(CONFIG_MATOM) += $(call cc-option,-march=atom,$(call cc-option,-march=core2,-march=i686)) \
|
||||
$(call cc-option,-mtune=atom,$(call cc-option,-mtune=generic))
|
||||
cflags-$(CONFIG_MATOM) += -march=atom
|
||||
|
||||
# AMD Elan support
|
||||
cflags-$(CONFIG_MELAN) += -march=i486
|
||||
|
||||
@@ -235,7 +235,7 @@ static void handle_relocations(void *output, unsigned long output_len,
|
||||
|
||||
/*
|
||||
* Process relocations: 32 bit relocations first then 64 bit after.
|
||||
* Three sets of binary relocations are added to the end of the kernel
|
||||
* Two sets of binary relocations are added to the end of the kernel
|
||||
* before compression. Each relocation table entry is the kernel
|
||||
* address of the location which needs to be updated stored as a
|
||||
* 32-bit value which is sign extended to 64 bits.
|
||||
@@ -245,8 +245,6 @@ static void handle_relocations(void *output, unsigned long output_len,
|
||||
* kernel bits...
|
||||
* 0 - zero terminator for 64 bit relocations
|
||||
* 64 bit relocation repeated
|
||||
* 0 - zero terminator for inverse 32 bit relocations
|
||||
* 32 bit inverse relocation repeated
|
||||
* 0 - zero terminator for 32 bit relocations
|
||||
* 32 bit relocation repeated
|
||||
*
|
||||
@@ -263,16 +261,6 @@ static void handle_relocations(void *output, unsigned long output_len,
|
||||
*(uint32_t *)ptr += delta;
|
||||
}
|
||||
#ifdef CONFIG_X86_64
|
||||
while (*--reloc) {
|
||||
long extended = *reloc;
|
||||
extended += map;
|
||||
|
||||
ptr = (unsigned long)extended;
|
||||
if (ptr < min_addr || ptr > max_addr)
|
||||
error("inverse 32-bit relocation outside of kernel!\n");
|
||||
|
||||
*(int32_t *)ptr -= delta;
|
||||
}
|
||||
for (reloc--; *reloc; reloc--) {
|
||||
long extended = *reloc;
|
||||
extended += map;
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
# global x86 required specific stuff
|
||||
# On 32-bit HIGHMEM4G is not allowed
|
||||
CONFIG_HIGHMEM64G=y
|
||||
CONFIG_64BIT=y
|
||||
|
||||
# These enable us to allow some of the
|
||||
|
||||
@@ -54,7 +54,6 @@ EXPORT_SYMBOL_GPL(mds_verw_sel);
|
||||
|
||||
THUNK warn_thunk_thunk, __warn_thunk
|
||||
|
||||
#ifndef CONFIG_X86_64
|
||||
/*
|
||||
* Clang's implementation of TLS stack cookies requires the variable in
|
||||
* question to be a TLS variable. If the variable happens to be defined as an
|
||||
@@ -68,4 +67,3 @@ THUNK warn_thunk_thunk, __warn_thunk
|
||||
#ifdef CONFIG_STACKPROTECTOR
|
||||
EXPORT_SYMBOL(__ref_stack_chk_guard);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -193,7 +193,7 @@ SYM_FUNC_START(__switch_to_asm)
|
||||
|
||||
#ifdef CONFIG_STACKPROTECTOR
|
||||
movq TASK_stack_canary(%rsi), %rbx
|
||||
movq %rbx, PER_CPU_VAR(fixed_percpu_data + FIXED_stack_canary)
|
||||
movq %rbx, PER_CPU_VAR(__stack_chk_guard)
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
@@ -4685,9 +4685,9 @@ static int adl_hw_config(struct perf_event *event)
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static enum hybrid_cpu_type adl_get_hybrid_cpu_type(void)
|
||||
static enum intel_cpu_type adl_get_hybrid_cpu_type(void)
|
||||
{
|
||||
return HYBRID_INTEL_CORE;
|
||||
return INTEL_CPU_TYPE_CORE;
|
||||
}
|
||||
|
||||
static inline bool erratum_hsw11(struct perf_event *event)
|
||||
@@ -5032,7 +5032,8 @@ static void intel_pmu_check_hybrid_pmus(struct x86_hybrid_pmu *pmu)
|
||||
|
||||
static struct x86_hybrid_pmu *find_hybrid_pmu_for_cpu(void)
|
||||
{
|
||||
u8 cpu_type = get_this_hybrid_cpu_type();
|
||||
struct cpuinfo_x86 *c = &cpu_data(smp_processor_id());
|
||||
enum intel_cpu_type cpu_type = c->topo.intel_type;
|
||||
int i;
|
||||
|
||||
/*
|
||||
@@ -5041,7 +5042,7 @@ static struct x86_hybrid_pmu *find_hybrid_pmu_for_cpu(void)
|
||||
* on it. There should be a fixup function provided for these
|
||||
* troublesome CPUs (->get_hybrid_cpu_type).
|
||||
*/
|
||||
if (cpu_type == HYBRID_INTEL_NONE) {
|
||||
if (cpu_type == INTEL_CPU_TYPE_UNKNOWN) {
|
||||
if (x86_pmu.get_hybrid_cpu_type)
|
||||
cpu_type = x86_pmu.get_hybrid_cpu_type();
|
||||
else
|
||||
@@ -5058,16 +5059,16 @@ static struct x86_hybrid_pmu *find_hybrid_pmu_for_cpu(void)
|
||||
enum hybrid_pmu_type pmu_type = x86_pmu.hybrid_pmu[i].pmu_type;
|
||||
u32 native_id;
|
||||
|
||||
if (cpu_type == HYBRID_INTEL_CORE && pmu_type == hybrid_big)
|
||||
if (cpu_type == INTEL_CPU_TYPE_CORE && pmu_type == hybrid_big)
|
||||
return &x86_pmu.hybrid_pmu[i];
|
||||
if (cpu_type == HYBRID_INTEL_ATOM) {
|
||||
if (cpu_type == INTEL_CPU_TYPE_ATOM) {
|
||||
if (x86_pmu.num_hybrid_pmus == 2 && pmu_type == hybrid_small)
|
||||
return &x86_pmu.hybrid_pmu[i];
|
||||
|
||||
native_id = get_this_hybrid_cpu_native_id();
|
||||
if (native_id == skt_native_id && pmu_type == hybrid_small)
|
||||
native_id = c->topo.intel_native_model_id;
|
||||
if (native_id == INTEL_ATOM_SKT_NATIVE_ID && pmu_type == hybrid_small)
|
||||
return &x86_pmu.hybrid_pmu[i];
|
||||
if (native_id == cmt_native_id && pmu_type == hybrid_tiny)
|
||||
if (native_id == INTEL_ATOM_CMT_NATIVE_ID && pmu_type == hybrid_tiny)
|
||||
return &x86_pmu.hybrid_pmu[i];
|
||||
}
|
||||
}
|
||||
@@ -6696,7 +6697,7 @@ __init int intel_pmu_init(void)
|
||||
case INTEL_ATOM_SILVERMONT_D:
|
||||
case INTEL_ATOM_SILVERMONT_MID:
|
||||
case INTEL_ATOM_AIRMONT:
|
||||
case INTEL_ATOM_AIRMONT_MID:
|
||||
case INTEL_ATOM_SILVERMONT_MID2:
|
||||
memcpy(hw_cache_event_ids, slm_hw_cache_event_ids,
|
||||
sizeof(hw_cache_event_ids));
|
||||
memcpy(hw_cache_extra_regs, slm_hw_cache_extra_regs,
|
||||
|
||||
@@ -669,18 +669,6 @@ enum {
|
||||
#define PERF_PEBS_DATA_SOURCE_GRT_MAX 0x10
|
||||
#define PERF_PEBS_DATA_SOURCE_GRT_MASK (PERF_PEBS_DATA_SOURCE_GRT_MAX - 1)
|
||||
|
||||
/*
|
||||
* CPUID.1AH.EAX[31:0] uniquely identifies the microarchitecture
|
||||
* of the core. Bits 31-24 indicates its core type (Core or Atom)
|
||||
* and Bits [23:0] indicates the native model ID of the core.
|
||||
* Core type and native model ID are defined in below enumerations.
|
||||
*/
|
||||
enum hybrid_cpu_type {
|
||||
HYBRID_INTEL_NONE,
|
||||
HYBRID_INTEL_ATOM = 0x20,
|
||||
HYBRID_INTEL_CORE = 0x40,
|
||||
};
|
||||
|
||||
#define X86_HYBRID_PMU_ATOM_IDX 0
|
||||
#define X86_HYBRID_PMU_CORE_IDX 1
|
||||
#define X86_HYBRID_PMU_TINY_IDX 2
|
||||
@@ -697,11 +685,6 @@ enum hybrid_pmu_type {
|
||||
hybrid_big_small_tiny = hybrid_big | hybrid_small_tiny,
|
||||
};
|
||||
|
||||
enum atom_native_id {
|
||||
cmt_native_id = 0x2, /* Crestmont */
|
||||
skt_native_id = 0x3, /* Skymont */
|
||||
};
|
||||
|
||||
struct x86_hybrid_pmu {
|
||||
struct pmu pmu;
|
||||
const char *name;
|
||||
@@ -994,7 +977,7 @@ struct x86_pmu {
|
||||
*/
|
||||
int num_hybrid_pmus;
|
||||
struct x86_hybrid_pmu *hybrid_pmu;
|
||||
enum hybrid_cpu_type (*get_hybrid_cpu_type) (void);
|
||||
enum intel_cpu_type (*get_hybrid_cpu_type) (void);
|
||||
};
|
||||
|
||||
struct x86_perf_task_context_opt {
|
||||
|
||||
@@ -239,5 +239,4 @@ void hyperv_setup_mmu_ops(void)
|
||||
|
||||
pr_info("Using hypercall for remote TLB flush\n");
|
||||
pv_ops.mmu.flush_tlb_multi = hyperv_flush_tlb_multi;
|
||||
pv_ops.mmu.tlb_remove_table = tlb_remove_table;
|
||||
}
|
||||
|
||||
@@ -236,10 +236,12 @@ static inline int alternatives_text_reserved(void *start, void *end)
|
||||
* references: i.e., if used for a function, it would add the PLT
|
||||
* suffix.
|
||||
*/
|
||||
#define alternative_call(oldfunc, newfunc, ft_flags, output, input...) \
|
||||
#define alternative_call(oldfunc, newfunc, ft_flags, output, input, clobbers...) \
|
||||
asm_inline volatile(ALTERNATIVE("call %c[old]", "call %c[new]", ft_flags) \
|
||||
: ALT_OUTPUT_SP(output) \
|
||||
: [old] "i" (oldfunc), [new] "i" (newfunc), ## input)
|
||||
: [old] "i" (oldfunc), [new] "i" (newfunc) \
|
||||
COMMA(input) \
|
||||
: clobbers)
|
||||
|
||||
/*
|
||||
* Like alternative_call, but there are two features and respective functions.
|
||||
@@ -248,24 +250,14 @@ static inline int alternatives_text_reserved(void *start, void *end)
|
||||
* Otherwise, old function is used.
|
||||
*/
|
||||
#define alternative_call_2(oldfunc, newfunc1, ft_flags1, newfunc2, ft_flags2, \
|
||||
output, input...) \
|
||||
output, input, clobbers...) \
|
||||
asm_inline volatile(ALTERNATIVE_2("call %c[old]", "call %c[new1]", ft_flags1, \
|
||||
"call %c[new2]", ft_flags2) \
|
||||
: ALT_OUTPUT_SP(output) \
|
||||
: [old] "i" (oldfunc), [new1] "i" (newfunc1), \
|
||||
[new2] "i" (newfunc2), ## input)
|
||||
|
||||
/*
|
||||
* use this macro(s) if you need more than one output parameter
|
||||
* in alternative_io
|
||||
*/
|
||||
#define ASM_OUTPUT2(a...) a
|
||||
|
||||
/*
|
||||
* use this macro if you need clobbers but no inputs in
|
||||
* alternative_{input,io,call}()
|
||||
*/
|
||||
#define ASM_NO_INPUT_CLOBBER(clbr...) "i" (0) : clbr
|
||||
[new2] "i" (newfunc2) \
|
||||
COMMA(input) \
|
||||
: clobbers)
|
||||
|
||||
#define ALT_OUTPUT_SP(...) ASM_CALL_CONSTRAINT, ## __VA_ARGS__
|
||||
|
||||
|
||||
@@ -99,8 +99,8 @@ static inline void native_apic_mem_write(u32 reg, u32 v)
|
||||
volatile u32 *addr = (volatile u32 *)(APIC_BASE + reg);
|
||||
|
||||
alternative_io("movl %0, %1", "xchgl %0, %1", X86_BUG_11AP,
|
||||
ASM_OUTPUT2("=r" (v), "=m" (*addr)),
|
||||
ASM_OUTPUT2("0" (v), "m" (*addr)));
|
||||
ASM_OUTPUT("=r" (v), "=m" (*addr)),
|
||||
ASM_INPUT("0" (v), "m" (*addr)));
|
||||
}
|
||||
|
||||
static inline u32 native_apic_mem_read(u32 reg)
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <asm/gsseg.h>
|
||||
#include <asm/nospec-branch.h>
|
||||
|
||||
#ifndef CONFIG_X86_CMPXCHG64
|
||||
#ifndef CONFIG_X86_CX8
|
||||
extern void cmpxchg8b_emu(void);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -213,6 +213,17 @@ static __always_inline __pure void *rip_rel_ptr(void *p)
|
||||
|
||||
/* For C file, we already have NOKPROBE_SYMBOL macro */
|
||||
|
||||
/* Insert a comma if args are non-empty */
|
||||
#define COMMA(x...) __COMMA(x)
|
||||
#define __COMMA(...) , ##__VA_ARGS__
|
||||
|
||||
/*
|
||||
* Combine multiple asm inline constraint args into a single arg for passing to
|
||||
* another macro.
|
||||
*/
|
||||
#define ASM_OUTPUT(x...) x
|
||||
#define ASM_INPUT(x...) x
|
||||
|
||||
/*
|
||||
* This output constraint should be used for any inline asm which has a "call"
|
||||
* instruction. Otherwise the asm may be inserted before the frame pointer
|
||||
|
||||
@@ -48,17 +48,20 @@ static __always_inline s64 arch_atomic64_read_nonatomic(const atomic64_t *v)
|
||||
ATOMIC64_EXPORT(atomic64_##sym)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_CMPXCHG64
|
||||
#define __alternative_atomic64(f, g, out, in...) \
|
||||
asm volatile("call %c[func]" \
|
||||
#ifdef CONFIG_X86_CX8
|
||||
#define __alternative_atomic64(f, g, out, in, clobbers...) \
|
||||
asm volatile("call %c[func]" \
|
||||
: ALT_OUTPUT_SP(out) \
|
||||
: [func] "i" (atomic64_##g##_cx8), ## in)
|
||||
: [func] "i" (atomic64_##g##_cx8) \
|
||||
COMMA(in) \
|
||||
: clobbers)
|
||||
|
||||
#define ATOMIC64_DECL(sym) ATOMIC64_DECL_ONE(sym##_cx8)
|
||||
#else
|
||||
#define __alternative_atomic64(f, g, out, in...) \
|
||||
alternative_call(atomic64_##f##_386, atomic64_##g##_cx8, \
|
||||
X86_FEATURE_CX8, ASM_OUTPUT2(out), ## in)
|
||||
#define __alternative_atomic64(f, g, out, in, clobbers...) \
|
||||
alternative_call(atomic64_##f##_386, atomic64_##g##_cx8, \
|
||||
X86_FEATURE_CX8, ASM_OUTPUT(out), \
|
||||
ASM_INPUT(in), clobbers)
|
||||
|
||||
#define ATOMIC64_DECL(sym) ATOMIC64_DECL_ONE(sym##_cx8); \
|
||||
ATOMIC64_DECL_ONE(sym##_386)
|
||||
@@ -69,8 +72,8 @@ ATOMIC64_DECL_ONE(inc_386);
|
||||
ATOMIC64_DECL_ONE(dec_386);
|
||||
#endif
|
||||
|
||||
#define alternative_atomic64(f, out, in...) \
|
||||
__alternative_atomic64(f, f, ASM_OUTPUT2(out), ## in)
|
||||
#define alternative_atomic64(f, out, in, clobbers...) \
|
||||
__alternative_atomic64(f, f, ASM_OUTPUT(out), ASM_INPUT(in), clobbers)
|
||||
|
||||
ATOMIC64_DECL(read);
|
||||
ATOMIC64_DECL(set);
|
||||
@@ -105,9 +108,10 @@ static __always_inline s64 arch_atomic64_xchg(atomic64_t *v, s64 n)
|
||||
s64 o;
|
||||
unsigned high = (unsigned)(n >> 32);
|
||||
unsigned low = (unsigned)n;
|
||||
alternative_atomic64(xchg, "=&A" (o),
|
||||
"S" (v), "b" (low), "c" (high)
|
||||
: "memory");
|
||||
alternative_atomic64(xchg,
|
||||
"=&A" (o),
|
||||
ASM_INPUT("S" (v), "b" (low), "c" (high)),
|
||||
"memory");
|
||||
return o;
|
||||
}
|
||||
#define arch_atomic64_xchg arch_atomic64_xchg
|
||||
@@ -116,23 +120,25 @@ static __always_inline void arch_atomic64_set(atomic64_t *v, s64 i)
|
||||
{
|
||||
unsigned high = (unsigned)(i >> 32);
|
||||
unsigned low = (unsigned)i;
|
||||
alternative_atomic64(set, /* no output */,
|
||||
"S" (v), "b" (low), "c" (high)
|
||||
: "eax", "edx", "memory");
|
||||
alternative_atomic64(set,
|
||||
/* no output */,
|
||||
ASM_INPUT("S" (v), "b" (low), "c" (high)),
|
||||
"eax", "edx", "memory");
|
||||
}
|
||||
|
||||
static __always_inline s64 arch_atomic64_read(const atomic64_t *v)
|
||||
{
|
||||
s64 r;
|
||||
alternative_atomic64(read, "=&A" (r), "c" (v) : "memory");
|
||||
alternative_atomic64(read, "=&A" (r), "c" (v), "memory");
|
||||
return r;
|
||||
}
|
||||
|
||||
static __always_inline s64 arch_atomic64_add_return(s64 i, atomic64_t *v)
|
||||
{
|
||||
alternative_atomic64(add_return,
|
||||
ASM_OUTPUT2("+A" (i), "+c" (v)),
|
||||
ASM_NO_INPUT_CLOBBER("memory"));
|
||||
ASM_OUTPUT("+A" (i), "+c" (v)),
|
||||
/* no input */,
|
||||
"memory");
|
||||
return i;
|
||||
}
|
||||
#define arch_atomic64_add_return arch_atomic64_add_return
|
||||
@@ -140,8 +146,9 @@ static __always_inline s64 arch_atomic64_add_return(s64 i, atomic64_t *v)
|
||||
static __always_inline s64 arch_atomic64_sub_return(s64 i, atomic64_t *v)
|
||||
{
|
||||
alternative_atomic64(sub_return,
|
||||
ASM_OUTPUT2("+A" (i), "+c" (v)),
|
||||
ASM_NO_INPUT_CLOBBER("memory"));
|
||||
ASM_OUTPUT("+A" (i), "+c" (v)),
|
||||
/* no input */,
|
||||
"memory");
|
||||
return i;
|
||||
}
|
||||
#define arch_atomic64_sub_return arch_atomic64_sub_return
|
||||
@@ -149,8 +156,10 @@ static __always_inline s64 arch_atomic64_sub_return(s64 i, atomic64_t *v)
|
||||
static __always_inline s64 arch_atomic64_inc_return(atomic64_t *v)
|
||||
{
|
||||
s64 a;
|
||||
alternative_atomic64(inc_return, "=&A" (a),
|
||||
"S" (v) : "memory", "ecx");
|
||||
alternative_atomic64(inc_return,
|
||||
"=&A" (a),
|
||||
"S" (v),
|
||||
"memory", "ecx");
|
||||
return a;
|
||||
}
|
||||
#define arch_atomic64_inc_return arch_atomic64_inc_return
|
||||
@@ -158,8 +167,10 @@ static __always_inline s64 arch_atomic64_inc_return(atomic64_t *v)
|
||||
static __always_inline s64 arch_atomic64_dec_return(atomic64_t *v)
|
||||
{
|
||||
s64 a;
|
||||
alternative_atomic64(dec_return, "=&A" (a),
|
||||
"S" (v) : "memory", "ecx");
|
||||
alternative_atomic64(dec_return,
|
||||
"=&A" (a),
|
||||
"S" (v),
|
||||
"memory", "ecx");
|
||||
return a;
|
||||
}
|
||||
#define arch_atomic64_dec_return arch_atomic64_dec_return
|
||||
@@ -167,28 +178,34 @@ static __always_inline s64 arch_atomic64_dec_return(atomic64_t *v)
|
||||
static __always_inline void arch_atomic64_add(s64 i, atomic64_t *v)
|
||||
{
|
||||
__alternative_atomic64(add, add_return,
|
||||
ASM_OUTPUT2("+A" (i), "+c" (v)),
|
||||
ASM_NO_INPUT_CLOBBER("memory"));
|
||||
ASM_OUTPUT("+A" (i), "+c" (v)),
|
||||
/* no input */,
|
||||
"memory");
|
||||
}
|
||||
|
||||
static __always_inline void arch_atomic64_sub(s64 i, atomic64_t *v)
|
||||
{
|
||||
__alternative_atomic64(sub, sub_return,
|
||||
ASM_OUTPUT2("+A" (i), "+c" (v)),
|
||||
ASM_NO_INPUT_CLOBBER("memory"));
|
||||
ASM_OUTPUT("+A" (i), "+c" (v)),
|
||||
/* no input */,
|
||||
"memory");
|
||||
}
|
||||
|
||||
static __always_inline void arch_atomic64_inc(atomic64_t *v)
|
||||
{
|
||||
__alternative_atomic64(inc, inc_return, /* no output */,
|
||||
"S" (v) : "memory", "eax", "ecx", "edx");
|
||||
__alternative_atomic64(inc, inc_return,
|
||||
/* no output */,
|
||||
"S" (v),
|
||||
"memory", "eax", "ecx", "edx");
|
||||
}
|
||||
#define arch_atomic64_inc arch_atomic64_inc
|
||||
|
||||
static __always_inline void arch_atomic64_dec(atomic64_t *v)
|
||||
{
|
||||
__alternative_atomic64(dec, dec_return, /* no output */,
|
||||
"S" (v) : "memory", "eax", "ecx", "edx");
|
||||
__alternative_atomic64(dec, dec_return,
|
||||
/* no output */,
|
||||
"S" (v),
|
||||
"memory", "eax", "ecx", "edx");
|
||||
}
|
||||
#define arch_atomic64_dec arch_atomic64_dec
|
||||
|
||||
@@ -197,8 +214,9 @@ static __always_inline int arch_atomic64_add_unless(atomic64_t *v, s64 a, s64 u)
|
||||
unsigned low = (unsigned)u;
|
||||
unsigned high = (unsigned)(u >> 32);
|
||||
alternative_atomic64(add_unless,
|
||||
ASM_OUTPUT2("+A" (a), "+c" (low), "+D" (high)),
|
||||
"S" (v) : "memory");
|
||||
ASM_OUTPUT("+A" (a), "+c" (low), "+D" (high)),
|
||||
"S" (v),
|
||||
"memory");
|
||||
return (int)a;
|
||||
}
|
||||
#define arch_atomic64_add_unless arch_atomic64_add_unless
|
||||
@@ -206,8 +224,10 @@ static __always_inline int arch_atomic64_add_unless(atomic64_t *v, s64 a, s64 u)
|
||||
static __always_inline int arch_atomic64_inc_not_zero(atomic64_t *v)
|
||||
{
|
||||
int r;
|
||||
alternative_atomic64(inc_not_zero, "=&a" (r),
|
||||
"S" (v) : "ecx", "edx", "memory");
|
||||
alternative_atomic64(inc_not_zero,
|
||||
"=&a" (r),
|
||||
"S" (v),
|
||||
"ecx", "edx", "memory");
|
||||
return r;
|
||||
}
|
||||
#define arch_atomic64_inc_not_zero arch_atomic64_inc_not_zero
|
||||
@@ -215,8 +235,10 @@ static __always_inline int arch_atomic64_inc_not_zero(atomic64_t *v)
|
||||
static __always_inline s64 arch_atomic64_dec_if_positive(atomic64_t *v)
|
||||
{
|
||||
s64 r;
|
||||
alternative_atomic64(dec_if_positive, "=&A" (r),
|
||||
"S" (v) : "ecx", "memory");
|
||||
alternative_atomic64(dec_if_positive,
|
||||
"=&A" (r),
|
||||
"S" (v),
|
||||
"ecx", "memory");
|
||||
return r;
|
||||
}
|
||||
#define arch_atomic64_dec_if_positive arch_atomic64_dec_if_positive
|
||||
|
||||
@@ -69,7 +69,7 @@ static __always_inline bool __try_cmpxchg64_local(volatile u64 *ptr, u64 *oldp,
|
||||
return __arch_try_cmpxchg64(ptr, oldp, new,);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_CMPXCHG64
|
||||
#ifdef CONFIG_X86_CX8
|
||||
|
||||
#define arch_cmpxchg64 __cmpxchg64
|
||||
|
||||
@@ -91,12 +91,14 @@ static __always_inline bool __try_cmpxchg64_local(volatile u64 *ptr, u64 *oldp,
|
||||
union __u64_halves o = { .full = (_old), }, \
|
||||
n = { .full = (_new), }; \
|
||||
\
|
||||
asm volatile(ALTERNATIVE(_lock_loc \
|
||||
"call cmpxchg8b_emu", \
|
||||
_lock "cmpxchg8b %a[ptr]", X86_FEATURE_CX8) \
|
||||
: ALT_OUTPUT_SP("+a" (o.low), "+d" (o.high)) \
|
||||
: "b" (n.low), "c" (n.high), [ptr] "S" (_ptr) \
|
||||
: "memory"); \
|
||||
asm_inline volatile( \
|
||||
ALTERNATIVE(_lock_loc \
|
||||
"call cmpxchg8b_emu", \
|
||||
_lock "cmpxchg8b %a[ptr]", X86_FEATURE_CX8) \
|
||||
: ALT_OUTPUT_SP("+a" (o.low), "+d" (o.high)) \
|
||||
: "b" (n.low), "c" (n.high), \
|
||||
[ptr] "S" (_ptr) \
|
||||
: "memory"); \
|
||||
\
|
||||
o.full; \
|
||||
})
|
||||
@@ -119,14 +121,16 @@ static __always_inline u64 arch_cmpxchg64_local(volatile u64 *ptr, u64 old, u64
|
||||
n = { .full = (_new), }; \
|
||||
bool ret; \
|
||||
\
|
||||
asm volatile(ALTERNATIVE(_lock_loc \
|
||||
"call cmpxchg8b_emu", \
|
||||
_lock "cmpxchg8b %a[ptr]", X86_FEATURE_CX8) \
|
||||
CC_SET(e) \
|
||||
: ALT_OUTPUT_SP(CC_OUT(e) (ret), \
|
||||
"+a" (o.low), "+d" (o.high)) \
|
||||
: "b" (n.low), "c" (n.high), [ptr] "S" (_ptr) \
|
||||
: "memory"); \
|
||||
asm_inline volatile( \
|
||||
ALTERNATIVE(_lock_loc \
|
||||
"call cmpxchg8b_emu", \
|
||||
_lock "cmpxchg8b %a[ptr]", X86_FEATURE_CX8) \
|
||||
CC_SET(e) \
|
||||
: ALT_OUTPUT_SP(CC_OUT(e) (ret), \
|
||||
"+a" (o.low), "+d" (o.high)) \
|
||||
: "b" (n.low), "c" (n.high), \
|
||||
[ptr] "S" (_ptr) \
|
||||
: "memory"); \
|
||||
\
|
||||
if (unlikely(!ret)) \
|
||||
*(_oldp) = o.full; \
|
||||
|
||||
@@ -49,20 +49,6 @@ static inline void split_lock_init(void) {}
|
||||
static inline void bus_lock_init(void) {}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CPU_SUP_INTEL
|
||||
u8 get_this_hybrid_cpu_type(void);
|
||||
u32 get_this_hybrid_cpu_native_id(void);
|
||||
#else
|
||||
static inline u8 get_this_hybrid_cpu_type(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline u32 get_this_hybrid_cpu_native_id(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_IA32_FEAT_CTL
|
||||
void init_ia32_feat_ctl(struct cpuinfo_x86 *c);
|
||||
#else
|
||||
|
||||
@@ -37,19 +37,15 @@ enum cpuid_leafs
|
||||
NR_CPUID_WORDS,
|
||||
};
|
||||
|
||||
#define X86_CAP_FMT_NUM "%d:%d"
|
||||
#define x86_cap_flag_num(flag) ((flag) >> 5), ((flag) & 31)
|
||||
|
||||
extern const char * const x86_cap_flags[NCAPINTS*32];
|
||||
extern const char * const x86_power_flags[32];
|
||||
#define X86_CAP_FMT "%s"
|
||||
#define x86_cap_flag(flag) x86_cap_flags[flag]
|
||||
|
||||
/*
|
||||
* In order to save room, we index into this array by doing
|
||||
* X86_BUG_<name> - NCAPINTS*32.
|
||||
*/
|
||||
extern const char * const x86_bug_flags[NBUGINTS*32];
|
||||
#define x86_bug_flag(flag) x86_bug_flags[flag]
|
||||
|
||||
#define test_cpu_cap(c, bit) \
|
||||
arch_test_bit(bit, (unsigned long *)((c)->x86_capability))
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#ifndef _ASM_X86_CPUID_H
|
||||
#define _ASM_X86_CPUID_H
|
||||
|
||||
#include <linux/build_bug.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <asm/string.h>
|
||||
|
||||
@@ -46,7 +46,6 @@ struct gdt_page {
|
||||
} __attribute__((aligned(PAGE_SIZE)));
|
||||
|
||||
DECLARE_PER_CPU_PAGE_ALIGNED(struct gdt_page, gdt_page);
|
||||
DECLARE_INIT_PER_CPU(gdt_page);
|
||||
|
||||
/* Provide the original GDT */
|
||||
static inline struct desc_struct *get_cpu_gdt_rw(unsigned int cpu)
|
||||
|
||||
@@ -54,8 +54,9 @@ typedef struct user_i387_struct elf_fpregset_t;
|
||||
#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */
|
||||
#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */
|
||||
#define R_X86_64_RELATIVE 8 /* Adjust by program base */
|
||||
#define R_X86_64_GOTPCREL 9 /* 32 bit signed pc relative
|
||||
offset to GOT */
|
||||
#define R_X86_64_GOTPCREL 9 /* 32 bit signed pc relative offset to GOT */
|
||||
#define R_X86_64_GOTPCRELX 41
|
||||
#define R_X86_64_REX_GOTPCRELX 42
|
||||
#define R_X86_64_32 10 /* Direct 32 bit zero extended */
|
||||
#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
|
||||
#define R_X86_64_16 12 /* Direct 16 bit zero extended */
|
||||
|
||||
@@ -110,9 +110,9 @@
|
||||
|
||||
#define INTEL_SAPPHIRERAPIDS_X IFM(6, 0x8F) /* Golden Cove */
|
||||
|
||||
#define INTEL_EMERALDRAPIDS_X IFM(6, 0xCF)
|
||||
#define INTEL_EMERALDRAPIDS_X IFM(6, 0xCF) /* Raptor Cove */
|
||||
|
||||
#define INTEL_GRANITERAPIDS_X IFM(6, 0xAD)
|
||||
#define INTEL_GRANITERAPIDS_X IFM(6, 0xAD) /* Redwood Cove */
|
||||
#define INTEL_GRANITERAPIDS_D IFM(6, 0xAE)
|
||||
|
||||
/* "Hybrid" Processors (P-Core/E-Core) */
|
||||
@@ -126,16 +126,16 @@
|
||||
#define INTEL_RAPTORLAKE_P IFM(6, 0xBA)
|
||||
#define INTEL_RAPTORLAKE_S IFM(6, 0xBF)
|
||||
|
||||
#define INTEL_METEORLAKE IFM(6, 0xAC)
|
||||
#define INTEL_METEORLAKE IFM(6, 0xAC) /* Redwood Cove / Crestmont */
|
||||
#define INTEL_METEORLAKE_L IFM(6, 0xAA)
|
||||
|
||||
#define INTEL_ARROWLAKE_H IFM(6, 0xC5)
|
||||
#define INTEL_ARROWLAKE_H IFM(6, 0xC5) /* Lion Cove / Skymont */
|
||||
#define INTEL_ARROWLAKE IFM(6, 0xC6)
|
||||
#define INTEL_ARROWLAKE_U IFM(6, 0xB5)
|
||||
|
||||
#define INTEL_LUNARLAKE_M IFM(6, 0xBD)
|
||||
#define INTEL_LUNARLAKE_M IFM(6, 0xBD) /* Lion Cove / Skymont */
|
||||
|
||||
#define INTEL_PANTHERLAKE_L IFM(6, 0xCC)
|
||||
#define INTEL_PANTHERLAKE_L IFM(6, 0xCC) /* Cougar Cove / Crestmont */
|
||||
|
||||
/* "Small Core" Processors (Atom/E-Core) */
|
||||
|
||||
@@ -149,9 +149,9 @@
|
||||
#define INTEL_ATOM_SILVERMONT IFM(6, 0x37) /* Bay Trail, Valleyview */
|
||||
#define INTEL_ATOM_SILVERMONT_D IFM(6, 0x4D) /* Avaton, Rangely */
|
||||
#define INTEL_ATOM_SILVERMONT_MID IFM(6, 0x4A) /* Merriefield */
|
||||
#define INTEL_ATOM_SILVERMONT_MID2 IFM(6, 0x5A) /* Anniedale */
|
||||
|
||||
#define INTEL_ATOM_AIRMONT IFM(6, 0x4C) /* Cherry Trail, Braswell */
|
||||
#define INTEL_ATOM_AIRMONT_MID IFM(6, 0x5A) /* Moorefield */
|
||||
#define INTEL_ATOM_AIRMONT_NP IFM(6, 0x75) /* Lightning Mountain */
|
||||
|
||||
#define INTEL_ATOM_GOLDMONT IFM(6, 0x5C) /* Apollo Lake */
|
||||
@@ -182,10 +182,23 @@
|
||||
/* Family 19 */
|
||||
#define INTEL_PANTHERCOVE_X IFM(19, 0x01) /* Diamond Rapids */
|
||||
|
||||
/* CPU core types */
|
||||
/*
|
||||
* Intel CPU core types
|
||||
*
|
||||
* CPUID.1AH.EAX[31:0] uniquely identifies the microarchitecture
|
||||
* of the core. Bits 31-24 indicates its core type (Core or Atom)
|
||||
* and Bits [23:0] indicates the native model ID of the core.
|
||||
* Core type and native model ID are defined in below enumerations.
|
||||
*/
|
||||
enum intel_cpu_type {
|
||||
INTEL_CPU_TYPE_UNKNOWN,
|
||||
INTEL_CPU_TYPE_ATOM = 0x20,
|
||||
INTEL_CPU_TYPE_CORE = 0x40,
|
||||
};
|
||||
|
||||
enum intel_native_id {
|
||||
INTEL_ATOM_CMT_NATIVE_ID = 0x2, /* Crestmont */
|
||||
INTEL_ATOM_SKT_NATIVE_ID = 0x3, /* Skymont */
|
||||
};
|
||||
|
||||
#endif /* _ASM_X86_INTEL_FAMILY_H */
|
||||
|
||||
@@ -175,6 +175,9 @@ extern void __iomem *ioremap_prot(resource_size_t offset, unsigned long size, un
|
||||
extern void __iomem *ioremap_encrypted(resource_size_t phys_addr, unsigned long size);
|
||||
#define ioremap_encrypted ioremap_encrypted
|
||||
|
||||
void *arch_memremap_wb(phys_addr_t phys_addr, size_t size, unsigned long flags);
|
||||
#define arch_memremap_wb arch_memremap_wb
|
||||
|
||||
/**
|
||||
* ioremap - map bus memory into CPU space
|
||||
* @offset: bus address of the memory
|
||||
|
||||
@@ -77,11 +77,11 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
|
||||
return hv_tdx_hypercall(control, input_address, output_address);
|
||||
|
||||
if (hv_isolation_type_snp() && !hyperv_paravisor_present) {
|
||||
__asm__ __volatile__("mov %4, %%r8\n"
|
||||
__asm__ __volatile__("mov %[output_address], %%r8\n"
|
||||
"vmmcall"
|
||||
: "=a" (hv_status), ASM_CALL_CONSTRAINT,
|
||||
"+c" (control), "+d" (input_address)
|
||||
: "r" (output_address)
|
||||
: [output_address] "r" (output_address)
|
||||
: "cc", "memory", "r8", "r9", "r10", "r11");
|
||||
return hv_status;
|
||||
}
|
||||
@@ -89,12 +89,12 @@ static inline u64 hv_do_hypercall(u64 control, void *input, void *output)
|
||||
if (!hv_hypercall_pg)
|
||||
return U64_MAX;
|
||||
|
||||
__asm__ __volatile__("mov %4, %%r8\n"
|
||||
__asm__ __volatile__("mov %[output_address], %%r8\n"
|
||||
CALL_NOSPEC
|
||||
: "=a" (hv_status), ASM_CALL_CONSTRAINT,
|
||||
"+c" (control), "+d" (input_address)
|
||||
: "r" (output_address),
|
||||
THUNK_TARGET(hv_hypercall_pg)
|
||||
: [output_address] "r" (output_address),
|
||||
THUNK_TARGET(hv_hypercall_pg)
|
||||
: "cc", "memory", "r8", "r9", "r10", "r11");
|
||||
#else
|
||||
u32 input_address_hi = upper_32_bits(input_address);
|
||||
@@ -187,18 +187,18 @@ static inline u64 _hv_do_fast_hypercall16(u64 control, u64 input1, u64 input2)
|
||||
return hv_tdx_hypercall(control, input1, input2);
|
||||
|
||||
if (hv_isolation_type_snp() && !hyperv_paravisor_present) {
|
||||
__asm__ __volatile__("mov %4, %%r8\n"
|
||||
__asm__ __volatile__("mov %[input2], %%r8\n"
|
||||
"vmmcall"
|
||||
: "=a" (hv_status), ASM_CALL_CONSTRAINT,
|
||||
"+c" (control), "+d" (input1)
|
||||
: "r" (input2)
|
||||
: [input2] "r" (input2)
|
||||
: "cc", "r8", "r9", "r10", "r11");
|
||||
} else {
|
||||
__asm__ __volatile__("mov %4, %%r8\n"
|
||||
__asm__ __volatile__("mov %[input2], %%r8\n"
|
||||
CALL_NOSPEC
|
||||
: "=a" (hv_status), ASM_CALL_CONSTRAINT,
|
||||
"+c" (control), "+d" (input1)
|
||||
: "r" (input2),
|
||||
: [input2] "r" (input2),
|
||||
THUNK_TARGET(hv_hypercall_pg)
|
||||
: "cc", "r8", "r9", "r10", "r11");
|
||||
}
|
||||
|
||||
@@ -198,9 +198,8 @@
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Equivalent to -mindirect-branch-cs-prefix; emit the 5 byte jmp/call
|
||||
* to the retpoline thunk with a CS prefix when the register requires
|
||||
* a RAX prefix byte to encode. Also see apply_retpolines().
|
||||
* Emits a conditional CS prefix that is compatible with
|
||||
* -mindirect-branch-cs-prefix.
|
||||
*/
|
||||
.macro __CS_PREFIX reg:req
|
||||
.irp rs,r8,r9,r10,r11,r12,r13,r14,r15
|
||||
@@ -420,20 +419,27 @@ static inline void call_depth_return_thunk(void) {}
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
|
||||
/*
|
||||
* Emits a conditional CS prefix that is compatible with
|
||||
* -mindirect-branch-cs-prefix.
|
||||
*/
|
||||
#define __CS_PREFIX(reg) \
|
||||
".irp rs,r8,r9,r10,r11,r12,r13,r14,r15\n" \
|
||||
".ifc \\rs," reg "\n" \
|
||||
".byte 0x2e\n" \
|
||||
".endif\n" \
|
||||
".endr\n"
|
||||
|
||||
/*
|
||||
* Inline asm uses the %V modifier which is only in newer GCC
|
||||
* which is ensured when CONFIG_MITIGATION_RETPOLINE is defined.
|
||||
*/
|
||||
# define CALL_NOSPEC \
|
||||
ALTERNATIVE_2( \
|
||||
ANNOTATE_RETPOLINE_SAFE \
|
||||
"call *%[thunk_target]\n", \
|
||||
"call __x86_indirect_thunk_%V[thunk_target]\n", \
|
||||
X86_FEATURE_RETPOLINE, \
|
||||
"lfence;\n" \
|
||||
ANNOTATE_RETPOLINE_SAFE \
|
||||
"call *%[thunk_target]\n", \
|
||||
X86_FEATURE_RETPOLINE_LFENCE)
|
||||
#ifdef CONFIG_MITIGATION_RETPOLINE
|
||||
#define CALL_NOSPEC __CS_PREFIX("%V[thunk_target]") \
|
||||
"call __x86_indirect_thunk_%V[thunk_target]\n"
|
||||
#else
|
||||
#define CALL_NOSPEC "call *%[thunk_target]\n"
|
||||
#endif
|
||||
|
||||
# define THUNK_TARGET(addr) [thunk_target] "r" (addr)
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
* a virtual address space of one gigabyte, which limits the
|
||||
* amount of physical memory you can use to about 950MB.
|
||||
*
|
||||
* If you want more physical memory than this then see the CONFIG_HIGHMEM4G
|
||||
* and CONFIG_HIGHMEM64G options in the kernel configuration.
|
||||
* If you want more physical memory than this then see the CONFIG_VMSPLIT_2G
|
||||
* and CONFIG_HIGHMEM4G options in the kernel configuration.
|
||||
*/
|
||||
#define __PAGE_OFFSET_BASE _AC(CONFIG_PAGE_OFFSET, UL)
|
||||
#define __PAGE_OFFSET __PAGE_OFFSET_BASE
|
||||
|
||||
@@ -55,8 +55,8 @@ static inline void clear_page(void *page)
|
||||
clear_page_rep, X86_FEATURE_REP_GOOD,
|
||||
clear_page_erms, X86_FEATURE_ERMS,
|
||||
"=D" (page),
|
||||
"D" (page)
|
||||
: "cc", "memory", "rax", "rcx");
|
||||
"D" (page),
|
||||
"cc", "memory", "rax", "rcx");
|
||||
}
|
||||
|
||||
void copy_page(void *to, void *from);
|
||||
|
||||
@@ -91,11 +91,6 @@ static inline void __flush_tlb_multi(const struct cpumask *cpumask,
|
||||
PVOP_VCALL2(mmu.flush_tlb_multi, cpumask, info);
|
||||
}
|
||||
|
||||
static inline void paravirt_tlb_remove_table(struct mmu_gather *tlb, void *table)
|
||||
{
|
||||
PVOP_VCALL2(mmu.tlb_remove_table, tlb, table);
|
||||
}
|
||||
|
||||
static inline void paravirt_arch_exit_mmap(struct mm_struct *mm)
|
||||
{
|
||||
PVOP_VCALL1(mmu.exit_mmap, mm);
|
||||
|
||||
@@ -134,8 +134,6 @@ struct pv_mmu_ops {
|
||||
void (*flush_tlb_multi)(const struct cpumask *cpus,
|
||||
const struct flush_tlb_info *info);
|
||||
|
||||
void (*tlb_remove_table)(struct mmu_gather *tlb, void *table);
|
||||
|
||||
/* Hook for intercepting the destruction of an mm_struct. */
|
||||
void (*exit_mmap)(struct mm_struct *mm);
|
||||
void (*notify_page_enc_status_changed)(unsigned long pfn, int npages, bool enc);
|
||||
|
||||
@@ -20,14 +20,9 @@
|
||||
|
||||
#define PER_CPU_VAR(var) __percpu(var)__percpu_rel
|
||||
|
||||
#ifdef CONFIG_X86_64_SMP
|
||||
# define INIT_PER_CPU_VAR(var) init_per_cpu__##var
|
||||
#else
|
||||
# define INIT_PER_CPU_VAR(var) var
|
||||
#endif
|
||||
|
||||
#else /* !__ASSEMBLY__: */
|
||||
|
||||
#include <linux/args.h>
|
||||
#include <linux/build_bug.h>
|
||||
#include <linux/stringify.h>
|
||||
#include <asm/asm.h>
|
||||
@@ -41,12 +36,7 @@
|
||||
# define __seg_fs __attribute__((address_space(__seg_fs)))
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
# define __percpu_seg_override __seg_gs
|
||||
#else
|
||||
# define __percpu_seg_override __seg_fs
|
||||
#endif
|
||||
|
||||
#define __percpu_seg_override CONCATENATE(__seg_, __percpu_seg)
|
||||
#define __percpu_prefix ""
|
||||
|
||||
#else /* !CONFIG_CC_HAS_NAMED_AS: */
|
||||
@@ -97,22 +87,6 @@
|
||||
#define __percpu_arg(x) __percpu_prefix "%" #x
|
||||
#define __force_percpu_arg(x) __force_percpu_prefix "%" #x
|
||||
|
||||
/*
|
||||
* Initialized pointers to per-CPU variables needed for the boot
|
||||
* processor need to use these macros to get the proper address
|
||||
* offset from __per_cpu_load on SMP.
|
||||
*
|
||||
* There also must be an entry in vmlinux_64.lds.S
|
||||
*/
|
||||
#define DECLARE_INIT_PER_CPU(var) \
|
||||
extern typeof(var) init_per_cpu_var(var)
|
||||
|
||||
#ifdef CONFIG_X86_64_SMP
|
||||
# define init_per_cpu_var(var) init_per_cpu__##var
|
||||
#else
|
||||
# define init_per_cpu_var(var) var
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For arch-specific code, we can use direct single-insn ops (they
|
||||
* don't give an lvalue though).
|
||||
@@ -128,15 +102,10 @@
|
||||
#define __pcpu_cast_4(val) ((u32)(((unsigned long) val) & 0xffffffff))
|
||||
#define __pcpu_cast_8(val) ((u64)(val))
|
||||
|
||||
#define __pcpu_op1_1(op, dst) op "b " dst
|
||||
#define __pcpu_op1_2(op, dst) op "w " dst
|
||||
#define __pcpu_op1_4(op, dst) op "l " dst
|
||||
#define __pcpu_op1_8(op, dst) op "q " dst
|
||||
|
||||
#define __pcpu_op2_1(op, src, dst) op "b " src ", " dst
|
||||
#define __pcpu_op2_2(op, src, dst) op "w " src ", " dst
|
||||
#define __pcpu_op2_4(op, src, dst) op "l " src ", " dst
|
||||
#define __pcpu_op2_8(op, src, dst) op "q " src ", " dst
|
||||
#define __pcpu_op_1(op) op "b "
|
||||
#define __pcpu_op_2(op) op "w "
|
||||
#define __pcpu_op_4(op) op "l "
|
||||
#define __pcpu_op_8(op) op "q "
|
||||
|
||||
#define __pcpu_reg_1(mod, x) mod "q" (x)
|
||||
#define __pcpu_reg_2(mod, x) mod "r" (x)
|
||||
@@ -168,7 +137,8 @@ do { \
|
||||
({ \
|
||||
__pcpu_type_##size pfo_val__; \
|
||||
\
|
||||
asm qual (__pcpu_op2_##size("mov", __percpu_arg([var]), "%[val]") \
|
||||
asm qual (__pcpu_op_##size("mov") \
|
||||
__percpu_arg([var]) ", %[val]" \
|
||||
: [val] __pcpu_reg_##size("=", pfo_val__) \
|
||||
: [var] "m" (__my_cpu_var(_var))); \
|
||||
\
|
||||
@@ -184,7 +154,8 @@ do { \
|
||||
pto_tmp__ = (_val); \
|
||||
(void)pto_tmp__; \
|
||||
} \
|
||||
asm qual(__pcpu_op2_##size("mov", "%[val]", __percpu_arg([var])) \
|
||||
asm qual (__pcpu_op_##size("mov") "%[val], " \
|
||||
__percpu_arg([var]) \
|
||||
: [var] "=m" (__my_cpu_var(_var)) \
|
||||
: [val] __pcpu_reg_imm_##size(pto_val__)); \
|
||||
} while (0)
|
||||
@@ -201,7 +172,8 @@ do { \
|
||||
({ \
|
||||
__pcpu_type_##size pfo_val__; \
|
||||
\
|
||||
asm(__pcpu_op2_##size("mov", __force_percpu_arg(a[var]), "%[val]") \
|
||||
asm(__pcpu_op_##size("mov") \
|
||||
__force_percpu_arg(a[var]) ", %[val]" \
|
||||
: [val] __pcpu_reg_##size("=", pfo_val__) \
|
||||
: [var] "i" (&(_var))); \
|
||||
\
|
||||
@@ -210,7 +182,7 @@ do { \
|
||||
|
||||
#define percpu_unary_op(size, qual, op, _var) \
|
||||
({ \
|
||||
asm qual (__pcpu_op1_##size(op, __percpu_arg([var])) \
|
||||
asm qual (__pcpu_op_##size(op) __percpu_arg([var]) \
|
||||
: [var] "+m" (__my_cpu_var(_var))); \
|
||||
})
|
||||
|
||||
@@ -223,7 +195,7 @@ do { \
|
||||
pto_tmp__ = (_val); \
|
||||
(void)pto_tmp__; \
|
||||
} \
|
||||
asm qual(__pcpu_op2_##size(op, "%[val]", __percpu_arg([var])) \
|
||||
asm qual (__pcpu_op_##size(op) "%[val], " __percpu_arg([var]) \
|
||||
: [var] "+m" (__my_cpu_var(_var)) \
|
||||
: [val] __pcpu_reg_imm_##size(pto_val__)); \
|
||||
} while (0)
|
||||
@@ -259,8 +231,8 @@ do { \
|
||||
({ \
|
||||
__pcpu_type_##size paro_tmp__ = __pcpu_cast_##size(_val); \
|
||||
\
|
||||
asm qual (__pcpu_op2_##size("xadd", "%[tmp]", \
|
||||
__percpu_arg([var])) \
|
||||
asm qual (__pcpu_op_##size("xadd") "%[tmp], " \
|
||||
__percpu_arg([var]) \
|
||||
: [tmp] __pcpu_reg_##size("+", paro_tmp__), \
|
||||
[var] "+m" (__my_cpu_var(_var)) \
|
||||
: : "memory"); \
|
||||
@@ -303,8 +275,8 @@ do { \
|
||||
__pcpu_type_##size pco_old__ = __pcpu_cast_##size(_oval); \
|
||||
__pcpu_type_##size pco_new__ = __pcpu_cast_##size(_nval); \
|
||||
\
|
||||
asm qual (__pcpu_op2_##size("cmpxchg", "%[nval]", \
|
||||
__percpu_arg([var])) \
|
||||
asm qual (__pcpu_op_##size("cmpxchg") "%[nval], " \
|
||||
__percpu_arg([var]) \
|
||||
: [oval] "+a" (pco_old__), \
|
||||
[var] "+m" (__my_cpu_var(_var)) \
|
||||
: [nval] __pcpu_reg_##size(, pco_new__) \
|
||||
@@ -320,8 +292,8 @@ do { \
|
||||
__pcpu_type_##size pco_old__ = *pco_oval__; \
|
||||
__pcpu_type_##size pco_new__ = __pcpu_cast_##size(_nval); \
|
||||
\
|
||||
asm qual (__pcpu_op2_##size("cmpxchg", "%[nval]", \
|
||||
__percpu_arg([var])) \
|
||||
asm qual (__pcpu_op_##size("cmpxchg") "%[nval], " \
|
||||
__percpu_arg([var]) \
|
||||
CC_SET(z) \
|
||||
: CC_OUT(z) (success), \
|
||||
[oval] "+a" (pco_old__), \
|
||||
@@ -348,15 +320,14 @@ do { \
|
||||
old__.var = _oval; \
|
||||
new__.var = _nval; \
|
||||
\
|
||||
asm qual (ALTERNATIVE("call this_cpu_cmpxchg8b_emu", \
|
||||
"cmpxchg8b " __percpu_arg([var]), X86_FEATURE_CX8) \
|
||||
: [var] "+m" (__my_cpu_var(_var)), \
|
||||
"+a" (old__.low), \
|
||||
"+d" (old__.high) \
|
||||
: "b" (new__.low), \
|
||||
"c" (new__.high), \
|
||||
"S" (&(_var)) \
|
||||
: "memory"); \
|
||||
asm_inline qual ( \
|
||||
ALTERNATIVE("call this_cpu_cmpxchg8b_emu", \
|
||||
"cmpxchg8b " __percpu_arg([var]), X86_FEATURE_CX8) \
|
||||
: ALT_OUTPUT_SP([var] "+m" (__my_cpu_var(_var)), \
|
||||
"+a" (old__.low), "+d" (old__.high)) \
|
||||
: "b" (new__.low), "c" (new__.high), \
|
||||
"S" (&(_var)) \
|
||||
: "memory"); \
|
||||
\
|
||||
old__.var; \
|
||||
})
|
||||
@@ -378,17 +349,16 @@ do { \
|
||||
old__.var = *_oval; \
|
||||
new__.var = _nval; \
|
||||
\
|
||||
asm qual (ALTERNATIVE("call this_cpu_cmpxchg8b_emu", \
|
||||
"cmpxchg8b " __percpu_arg([var]), X86_FEATURE_CX8) \
|
||||
CC_SET(z) \
|
||||
: CC_OUT(z) (success), \
|
||||
[var] "+m" (__my_cpu_var(_var)), \
|
||||
"+a" (old__.low), \
|
||||
"+d" (old__.high) \
|
||||
: "b" (new__.low), \
|
||||
"c" (new__.high), \
|
||||
"S" (&(_var)) \
|
||||
: "memory"); \
|
||||
asm_inline qual ( \
|
||||
ALTERNATIVE("call this_cpu_cmpxchg8b_emu", \
|
||||
"cmpxchg8b " __percpu_arg([var]), X86_FEATURE_CX8) \
|
||||
CC_SET(z) \
|
||||
: ALT_OUTPUT_SP(CC_OUT(z) (success), \
|
||||
[var] "+m" (__my_cpu_var(_var)), \
|
||||
"+a" (old__.low), "+d" (old__.high)) \
|
||||
: "b" (new__.low), "c" (new__.high), \
|
||||
"S" (&(_var)) \
|
||||
: "memory"); \
|
||||
if (unlikely(!success)) \
|
||||
*_oval = old__.var; \
|
||||
\
|
||||
@@ -419,15 +389,14 @@ do { \
|
||||
old__.var = _oval; \
|
||||
new__.var = _nval; \
|
||||
\
|
||||
asm qual (ALTERNATIVE("call this_cpu_cmpxchg16b_emu", \
|
||||
"cmpxchg16b " __percpu_arg([var]), X86_FEATURE_CX16) \
|
||||
: [var] "+m" (__my_cpu_var(_var)), \
|
||||
"+a" (old__.low), \
|
||||
"+d" (old__.high) \
|
||||
: "b" (new__.low), \
|
||||
"c" (new__.high), \
|
||||
"S" (&(_var)) \
|
||||
: "memory"); \
|
||||
asm_inline qual ( \
|
||||
ALTERNATIVE("call this_cpu_cmpxchg16b_emu", \
|
||||
"cmpxchg16b " __percpu_arg([var]), X86_FEATURE_CX16) \
|
||||
: ALT_OUTPUT_SP([var] "+m" (__my_cpu_var(_var)), \
|
||||
"+a" (old__.low), "+d" (old__.high)) \
|
||||
: "b" (new__.low), "c" (new__.high), \
|
||||
"S" (&(_var)) \
|
||||
: "memory"); \
|
||||
\
|
||||
old__.var; \
|
||||
})
|
||||
@@ -449,19 +418,19 @@ do { \
|
||||
old__.var = *_oval; \
|
||||
new__.var = _nval; \
|
||||
\
|
||||
asm qual (ALTERNATIVE("call this_cpu_cmpxchg16b_emu", \
|
||||
"cmpxchg16b " __percpu_arg([var]), X86_FEATURE_CX16) \
|
||||
CC_SET(z) \
|
||||
: CC_OUT(z) (success), \
|
||||
[var] "+m" (__my_cpu_var(_var)), \
|
||||
"+a" (old__.low), \
|
||||
"+d" (old__.high) \
|
||||
: "b" (new__.low), \
|
||||
"c" (new__.high), \
|
||||
"S" (&(_var)) \
|
||||
: "memory"); \
|
||||
asm_inline qual ( \
|
||||
ALTERNATIVE("call this_cpu_cmpxchg16b_emu", \
|
||||
"cmpxchg16b " __percpu_arg([var]), X86_FEATURE_CX16) \
|
||||
CC_SET(z) \
|
||||
: ALT_OUTPUT_SP(CC_OUT(z) (success), \
|
||||
[var] "+m" (__my_cpu_var(_var)), \
|
||||
"+a" (old__.low), "+d" (old__.high)) \
|
||||
: "b" (new__.low), "c" (new__.high), \
|
||||
"S" (&(_var)) \
|
||||
: "memory"); \
|
||||
if (unlikely(!success)) \
|
||||
*_oval = old__.var; \
|
||||
\
|
||||
likely(success); \
|
||||
})
|
||||
|
||||
|
||||
@@ -29,11 +29,6 @@ static inline void paravirt_release_pud(unsigned long pfn) {}
|
||||
static inline void paravirt_release_p4d(unsigned long pfn) {}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Flags to use when allocating a user page table page.
|
||||
*/
|
||||
extern gfp_t __userpte_alloc_gfp;
|
||||
|
||||
#ifdef CONFIG_MITIGATION_PAGE_TABLE_ISOLATION
|
||||
/*
|
||||
* Instead of one PGD, we acquire two PGDs. Being order-1, it is
|
||||
|
||||
@@ -60,18 +60,13 @@ struct vm86;
|
||||
# define ARCH_MIN_MMSTRUCT_ALIGN 0
|
||||
#endif
|
||||
|
||||
enum tlb_infos {
|
||||
ENTRIES,
|
||||
NR_INFO
|
||||
};
|
||||
|
||||
extern u16 __read_mostly tlb_lli_4k[NR_INFO];
|
||||
extern u16 __read_mostly tlb_lli_2m[NR_INFO];
|
||||
extern u16 __read_mostly tlb_lli_4m[NR_INFO];
|
||||
extern u16 __read_mostly tlb_lld_4k[NR_INFO];
|
||||
extern u16 __read_mostly tlb_lld_2m[NR_INFO];
|
||||
extern u16 __read_mostly tlb_lld_4m[NR_INFO];
|
||||
extern u16 __read_mostly tlb_lld_1g[NR_INFO];
|
||||
extern u16 __read_mostly tlb_lli_4k;
|
||||
extern u16 __read_mostly tlb_lli_2m;
|
||||
extern u16 __read_mostly tlb_lli_4m;
|
||||
extern u16 __read_mostly tlb_lld_4k;
|
||||
extern u16 __read_mostly tlb_lld_2m;
|
||||
extern u16 __read_mostly tlb_lld_4m;
|
||||
extern u16 __read_mostly tlb_lld_1g;
|
||||
|
||||
/*
|
||||
* CPU type and hardware bug flags. Kept separately for each CPU.
|
||||
@@ -234,7 +229,7 @@ static inline unsigned long long l1tf_pfn_limit(void)
|
||||
void init_cpu_devs(void);
|
||||
void get_cpu_vendor(struct cpuinfo_x86 *c);
|
||||
extern void early_cpu_init(void);
|
||||
extern void identify_secondary_cpu(struct cpuinfo_x86 *);
|
||||
extern void identify_secondary_cpu(unsigned int cpu);
|
||||
extern void print_cpu_info(struct cpuinfo_x86 *);
|
||||
void print_cpu_msr(struct cpuinfo_x86 *);
|
||||
|
||||
@@ -421,36 +416,20 @@ struct irq_stack {
|
||||
} __aligned(IRQ_STACK_SIZE);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
struct fixed_percpu_data {
|
||||
/*
|
||||
* GCC hardcodes the stack canary as %gs:40. Since the
|
||||
* irq_stack is the object at %gs:0, we reserve the bottom
|
||||
* 48 bytes of the irq stack for the canary.
|
||||
*
|
||||
* Once we are willing to require -mstack-protector-guard-symbol=
|
||||
* support for x86_64 stackprotector, we can get rid of this.
|
||||
*/
|
||||
char gs_base[40];
|
||||
unsigned long stack_canary;
|
||||
};
|
||||
|
||||
DECLARE_PER_CPU_FIRST(struct fixed_percpu_data, fixed_percpu_data) __visible;
|
||||
DECLARE_INIT_PER_CPU(fixed_percpu_data);
|
||||
|
||||
static inline unsigned long cpu_kernelmode_gs_base(int cpu)
|
||||
{
|
||||
return (unsigned long)per_cpu(fixed_percpu_data.gs_base, cpu);
|
||||
#ifdef CONFIG_SMP
|
||||
return per_cpu_offset(cpu);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
extern asmlinkage void entry_SYSCALL32_ignore(void);
|
||||
|
||||
/* Save actual FS/GS selectors and bases to current->thread */
|
||||
void current_save_fsgs(void);
|
||||
#else /* X86_64 */
|
||||
#ifdef CONFIG_STACKPROTECTOR
|
||||
DECLARE_PER_CPU(unsigned long, __stack_chk_guard);
|
||||
#endif
|
||||
#endif /* !X86_64 */
|
||||
#endif /* X86_64 */
|
||||
|
||||
struct perf_event;
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
# define NEED_PAE 0
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_CMPXCHG64
|
||||
#ifdef CONFIG_X86_CX8
|
||||
# define NEED_CX8 (1<<(X86_FEATURE_CX8 & 31))
|
||||
#else
|
||||
# define NEED_CX8 0
|
||||
|
||||
@@ -114,13 +114,12 @@ void wbinvd_on_cpu(int cpu);
|
||||
int wbinvd_on_all_cpus(void);
|
||||
|
||||
void smp_kick_mwait_play_dead(void);
|
||||
void __noreturn mwait_play_dead(unsigned int eax_hint);
|
||||
|
||||
void native_smp_send_reschedule(int cpu);
|
||||
void native_send_call_func_ipi(const struct cpumask *mask);
|
||||
void native_send_call_func_single_ipi(int cpu);
|
||||
|
||||
void smp_store_cpu_info(int id);
|
||||
|
||||
asmlinkage __visible void smp_reboot_interrupt(void);
|
||||
__visible void smp_reschedule_interrupt(struct pt_regs *regs);
|
||||
__visible void smp_call_function_interrupt(struct pt_regs *regs);
|
||||
@@ -158,6 +157,8 @@ static inline struct cpumask *cpu_llc_shared_mask(int cpu)
|
||||
{
|
||||
return (struct cpumask *)cpumask_of(0);
|
||||
}
|
||||
|
||||
static inline void __noreturn mwait_play_dead(unsigned int eax_hint) { BUG(); }
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
#ifdef CONFIG_DEBUG_NMI_SELFTEST
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Header file for STMicroelectronics ConneXt (STA2X11) IOHub
|
||||
*/
|
||||
#ifndef __ASM_STA2X11_H
|
||||
#define __ASM_STA2X11_H
|
||||
|
||||
#include <linux/pci.h>
|
||||
|
||||
/* This needs to be called from the MFD to configure its sub-devices */
|
||||
struct sta2x11_instance *sta2x11_get_instance(struct pci_dev *pdev);
|
||||
|
||||
#endif /* __ASM_STA2X11_H */
|
||||
@@ -2,26 +2,10 @@
|
||||
/*
|
||||
* GCC stack protector support.
|
||||
*
|
||||
* Stack protector works by putting predefined pattern at the start of
|
||||
* Stack protector works by putting a predefined pattern at the start of
|
||||
* the stack frame and verifying that it hasn't been overwritten when
|
||||
* returning from the function. The pattern is called stack canary
|
||||
* and unfortunately gcc historically required it to be at a fixed offset
|
||||
* from the percpu segment base. On x86_64, the offset is 40 bytes.
|
||||
*
|
||||
* The same segment is shared by percpu area and stack canary. On
|
||||
* x86_64, percpu symbols are zero based and %gs (64-bit) points to the
|
||||
* base of percpu area. The first occupant of the percpu area is always
|
||||
* fixed_percpu_data which contains stack_canary at the appropriate
|
||||
* offset. On x86_32, the stack canary is just a regular percpu
|
||||
* variable.
|
||||
*
|
||||
* Putting percpu data in %fs on 32-bit is a minor optimization compared to
|
||||
* using %gs. Since 32-bit userspace normally has %fs == 0, we are likely
|
||||
* to load 0 into %fs on exit to usermode, whereas with percpu data in
|
||||
* %gs, we are likely to load a non-null %gs on return to user mode.
|
||||
*
|
||||
* Once we are willing to require GCC 8.1 or better for 64-bit stackprotector
|
||||
* support, we can remove some of this complexity.
|
||||
* returning from the function. The pattern is called the stack canary
|
||||
* and is a unique value for each task.
|
||||
*/
|
||||
|
||||
#ifndef _ASM_STACKPROTECTOR_H
|
||||
@@ -36,6 +20,8 @@
|
||||
|
||||
#include <linux/sched.h>
|
||||
|
||||
DECLARE_PER_CPU(unsigned long, __stack_chk_guard);
|
||||
|
||||
/*
|
||||
* Initialize the stackprotector canary value.
|
||||
*
|
||||
@@ -51,25 +37,13 @@ static __always_inline void boot_init_stack_canary(void)
|
||||
{
|
||||
unsigned long canary = get_random_canary();
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
BUILD_BUG_ON(offsetof(struct fixed_percpu_data, stack_canary) != 40);
|
||||
#endif
|
||||
|
||||
current->stack_canary = canary;
|
||||
#ifdef CONFIG_X86_64
|
||||
this_cpu_write(fixed_percpu_data.stack_canary, canary);
|
||||
#else
|
||||
this_cpu_write(__stack_chk_guard, canary);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void cpu_init_stack_canary(int cpu, struct task_struct *idle)
|
||||
{
|
||||
#ifdef CONFIG_X86_64
|
||||
per_cpu(fixed_percpu_data.stack_canary, cpu) = idle->stack_canary;
|
||||
#else
|
||||
per_cpu(__stack_chk_guard, cpu) = idle->stack_canary;
|
||||
#endif
|
||||
}
|
||||
|
||||
#else /* STACKPROTECTOR */
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
#define MODULE_PROC_FAMILY "586TSC "
|
||||
#elif defined CONFIG_M586MMX
|
||||
#define MODULE_PROC_FAMILY "586MMX "
|
||||
#elif defined CONFIG_MCORE2
|
||||
#define MODULE_PROC_FAMILY "CORE2 "
|
||||
#elif defined CONFIG_MATOM
|
||||
#define MODULE_PROC_FAMILY "ATOM "
|
||||
#elif defined CONFIG_M686
|
||||
@@ -33,8 +31,6 @@
|
||||
#define MODULE_PROC_FAMILY "K6 "
|
||||
#elif defined CONFIG_MK7
|
||||
#define MODULE_PROC_FAMILY "K7 "
|
||||
#elif defined CONFIG_MK8
|
||||
#define MODULE_PROC_FAMILY "K8 "
|
||||
#elif defined CONFIG_MELAN
|
||||
#define MODULE_PROC_FAMILY "ELAN "
|
||||
#elif defined CONFIG_MCRUSOE
|
||||
|
||||
@@ -44,6 +44,8 @@ KCOV_INSTRUMENT_unwind_orc.o := n
|
||||
KCOV_INSTRUMENT_unwind_frame.o := n
|
||||
KCOV_INSTRUMENT_unwind_guess.o := n
|
||||
|
||||
CFLAGS_head32.o := -fno-stack-protector
|
||||
CFLAGS_head64.o := -fno-stack-protector
|
||||
CFLAGS_irq.o := -I $(src)/../include/asm/trace
|
||||
|
||||
obj-y += head_$(BITS).o
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <asm/cpuid.h>
|
||||
#include <asm/mwait.h>
|
||||
#include <asm/special_insns.h>
|
||||
#include <asm/smp.h>
|
||||
|
||||
/*
|
||||
* Initialize bm_flags based on the CPU cache properties
|
||||
@@ -205,6 +206,16 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_processor_ffh_cstate_probe);
|
||||
|
||||
void __noreturn acpi_processor_ffh_play_dead(struct acpi_processor_cx *cx)
|
||||
{
|
||||
unsigned int cpu = smp_processor_id();
|
||||
struct cstate_entry *percpu_entry;
|
||||
|
||||
percpu_entry = per_cpu_ptr(cpu_cstate_entry, cpu);
|
||||
mwait_play_dead(percpu_entry->states[cx->index].eax);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(acpi_processor_ffh_play_dead);
|
||||
|
||||
void __cpuidle acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cx)
|
||||
{
|
||||
unsigned int cpu = smp_processor_id();
|
||||
|
||||
@@ -23,8 +23,5 @@ obj-$(CONFIG_X86_X2APIC) += x2apic_cluster.o
|
||||
obj-y += apic_flat_64.o
|
||||
endif
|
||||
|
||||
# APIC probe will depend on the listing order here
|
||||
obj-$(CONFIG_X86_BIGSMP) += bigsmp_32.o
|
||||
|
||||
# For 32bit, probe_32 need to be listed last
|
||||
obj-$(CONFIG_X86_LOCAL_APIC) += probe_$(BITS).o
|
||||
|
||||
@@ -1371,8 +1371,6 @@ void __init apic_intr_mode_init(void)
|
||||
|
||||
x86_64_probe_apic();
|
||||
|
||||
x86_32_install_bigsmp();
|
||||
|
||||
if (x86_platform.apic_post_init)
|
||||
x86_platform.apic_post_init();
|
||||
|
||||
@@ -1674,7 +1672,6 @@ static __init void apic_read_boot_cpu_id(bool x2apic)
|
||||
boot_cpu_apic_version = GET_APIC_VERSION(apic_read(APIC_LVR));
|
||||
}
|
||||
topology_register_boot_apic(boot_cpu_physical_apicid);
|
||||
x86_32_probe_bigsmp_early();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_X2APIC
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* APIC driver for "bigsmp" xAPIC machines with more than 8 virtual CPUs.
|
||||
*
|
||||
* Drives the local APIC in "clustered mode".
|
||||
*/
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/smp.h>
|
||||
|
||||
#include <asm/apic.h>
|
||||
#include <asm/io_apic.h>
|
||||
|
||||
#include "local.h"
|
||||
|
||||
static u32 bigsmp_get_apic_id(u32 x)
|
||||
{
|
||||
return (x >> 24) & 0xFF;
|
||||
}
|
||||
|
||||
static void bigsmp_send_IPI_allbutself(int vector)
|
||||
{
|
||||
default_send_IPI_mask_allbutself_phys(cpu_online_mask, vector);
|
||||
}
|
||||
|
||||
static void bigsmp_send_IPI_all(int vector)
|
||||
{
|
||||
default_send_IPI_mask_sequence_phys(cpu_online_mask, vector);
|
||||
}
|
||||
|
||||
static int dmi_bigsmp; /* can be set by dmi scanners */
|
||||
|
||||
static int hp_ht_bigsmp(const struct dmi_system_id *d)
|
||||
{
|
||||
printk(KERN_NOTICE "%s detected: force use of apic=bigsmp\n", d->ident);
|
||||
dmi_bigsmp = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static const struct dmi_system_id bigsmp_dmi_table[] = {
|
||||
{ hp_ht_bigsmp, "HP ProLiant DL760 G2",
|
||||
{ DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
|
||||
DMI_MATCH(DMI_BIOS_VERSION, "P44-"),
|
||||
}
|
||||
},
|
||||
|
||||
{ hp_ht_bigsmp, "HP ProLiant DL740",
|
||||
{ DMI_MATCH(DMI_BIOS_VENDOR, "HP"),
|
||||
DMI_MATCH(DMI_BIOS_VERSION, "P47-"),
|
||||
}
|
||||
},
|
||||
{ } /* NULL entry stops DMI scanning */
|
||||
};
|
||||
|
||||
static int probe_bigsmp(void)
|
||||
{
|
||||
return dmi_check_system(bigsmp_dmi_table);
|
||||
}
|
||||
|
||||
static struct apic apic_bigsmp __ro_after_init = {
|
||||
|
||||
.name = "bigsmp",
|
||||
.probe = probe_bigsmp,
|
||||
|
||||
.dest_mode_logical = false,
|
||||
|
||||
.disable_esr = 1,
|
||||
|
||||
.cpu_present_to_apicid = default_cpu_present_to_apicid,
|
||||
|
||||
.max_apic_id = 0xFE,
|
||||
.get_apic_id = bigsmp_get_apic_id,
|
||||
|
||||
.calc_dest_apicid = apic_default_calc_apicid,
|
||||
|
||||
.send_IPI = default_send_IPI_single_phys,
|
||||
.send_IPI_mask = default_send_IPI_mask_sequence_phys,
|
||||
.send_IPI_mask_allbutself = NULL,
|
||||
.send_IPI_allbutself = bigsmp_send_IPI_allbutself,
|
||||
.send_IPI_all = bigsmp_send_IPI_all,
|
||||
.send_IPI_self = default_send_IPI_self,
|
||||
|
||||
.read = native_apic_mem_read,
|
||||
.write = native_apic_mem_write,
|
||||
.eoi = native_apic_mem_eoi,
|
||||
.icr_read = native_apic_icr_read,
|
||||
.icr_write = native_apic_icr_write,
|
||||
.wait_icr_idle = apic_mem_wait_icr_idle,
|
||||
.safe_wait_icr_idle = apic_mem_wait_icr_idle_timeout,
|
||||
};
|
||||
|
||||
bool __init apic_bigsmp_possible(bool cmdline_override)
|
||||
{
|
||||
return apic == &apic_bigsmp || !cmdline_override;
|
||||
}
|
||||
|
||||
void __init apic_bigsmp_force(void)
|
||||
{
|
||||
if (apic != &apic_bigsmp)
|
||||
apic_install_driver(&apic_bigsmp);
|
||||
}
|
||||
|
||||
apic_driver(apic_bigsmp);
|
||||
@@ -65,17 +65,4 @@ void default_send_IPI_self(int vector);
|
||||
void default_send_IPI_mask_sequence_logical(const struct cpumask *mask, int vector);
|
||||
void default_send_IPI_mask_allbutself_logical(const struct cpumask *mask, int vector);
|
||||
void default_send_IPI_mask_logical(const struct cpumask *mask, int vector);
|
||||
void x86_32_probe_bigsmp_early(void);
|
||||
void x86_32_install_bigsmp(void);
|
||||
#else
|
||||
static inline void x86_32_probe_bigsmp_early(void) { }
|
||||
static inline void x86_32_install_bigsmp(void) { }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_BIGSMP
|
||||
bool apic_bigsmp_possible(bool cmdline_selected);
|
||||
void apic_bigsmp_force(void);
|
||||
#else
|
||||
static inline bool apic_bigsmp_possible(bool cmdline_selected) { return false; };
|
||||
static inline void apic_bigsmp_force(void) { }
|
||||
#endif
|
||||
|
||||
@@ -93,35 +93,6 @@ static int __init parse_apic(char *arg)
|
||||
}
|
||||
early_param("apic", parse_apic);
|
||||
|
||||
void __init x86_32_probe_bigsmp_early(void)
|
||||
{
|
||||
if (nr_cpu_ids <= 8 || xen_pv_domain())
|
||||
return;
|
||||
|
||||
if (IS_ENABLED(CONFIG_X86_BIGSMP)) {
|
||||
switch (boot_cpu_data.x86_vendor) {
|
||||
case X86_VENDOR_INTEL:
|
||||
if (!APIC_XAPIC(boot_cpu_apic_version))
|
||||
break;
|
||||
/* P4 and above */
|
||||
fallthrough;
|
||||
case X86_VENDOR_HYGON:
|
||||
case X86_VENDOR_AMD:
|
||||
if (apic_bigsmp_possible(cmdline_apic))
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pr_info("Limiting to 8 possible CPUs\n");
|
||||
set_nr_cpu_ids(8);
|
||||
}
|
||||
|
||||
void __init x86_32_install_bigsmp(void)
|
||||
{
|
||||
if (nr_cpu_ids > 8 && !xen_pv_domain())
|
||||
apic_bigsmp_force();
|
||||
}
|
||||
|
||||
void __init x86_32_probe_apic(void)
|
||||
{
|
||||
if (!cmdline_apic) {
|
||||
|
||||
@@ -54,11 +54,5 @@ int main(void)
|
||||
BLANK();
|
||||
#undef ENTRY
|
||||
|
||||
BLANK();
|
||||
|
||||
#ifdef CONFIG_STACKPROTECTOR
|
||||
OFFSET(FIXED_stack_canary, fixed_percpu_data, stack_canary);
|
||||
BLANK();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -632,7 +632,7 @@ static void init_amd_k8(struct cpuinfo_x86 *c)
|
||||
* (model = 0x14) and later actually support it.
|
||||
* (AMD Erratum #110, docId: 25759).
|
||||
*/
|
||||
if (c->x86_model < 0x14 && cpu_has(c, X86_FEATURE_LAHF_LM)) {
|
||||
if (c->x86_model < 0x14 && cpu_has(c, X86_FEATURE_LAHF_LM) && !cpu_has(c, X86_FEATURE_HYPERVISOR)) {
|
||||
clear_cpu_cap(c, X86_FEATURE_LAHF_LM);
|
||||
if (!rdmsrl_amd_safe(0xc001100d, &value)) {
|
||||
value &= ~BIT_64(32);
|
||||
@@ -1105,8 +1105,8 @@ static void cpu_detect_tlb_amd(struct cpuinfo_x86 *c)
|
||||
|
||||
cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
|
||||
|
||||
tlb_lld_4k[ENTRIES] = (ebx >> 16) & mask;
|
||||
tlb_lli_4k[ENTRIES] = ebx & mask;
|
||||
tlb_lld_4k = (ebx >> 16) & mask;
|
||||
tlb_lli_4k = ebx & mask;
|
||||
|
||||
/*
|
||||
* K8 doesn't have 2M/4M entries in the L2 TLB so read out the L1 TLB
|
||||
@@ -1119,26 +1119,26 @@ static void cpu_detect_tlb_amd(struct cpuinfo_x86 *c)
|
||||
|
||||
/* Handle DTLB 2M and 4M sizes, fall back to L1 if L2 is disabled */
|
||||
if (!((eax >> 16) & mask))
|
||||
tlb_lld_2m[ENTRIES] = (cpuid_eax(0x80000005) >> 16) & 0xff;
|
||||
tlb_lld_2m = (cpuid_eax(0x80000005) >> 16) & 0xff;
|
||||
else
|
||||
tlb_lld_2m[ENTRIES] = (eax >> 16) & mask;
|
||||
tlb_lld_2m = (eax >> 16) & mask;
|
||||
|
||||
/* a 4M entry uses two 2M entries */
|
||||
tlb_lld_4m[ENTRIES] = tlb_lld_2m[ENTRIES] >> 1;
|
||||
tlb_lld_4m = tlb_lld_2m >> 1;
|
||||
|
||||
/* Handle ITLB 2M and 4M sizes, fall back to L1 if L2 is disabled */
|
||||
if (!(eax & mask)) {
|
||||
/* Erratum 658 */
|
||||
if (c->x86 == 0x15 && c->x86_model <= 0x1f) {
|
||||
tlb_lli_2m[ENTRIES] = 1024;
|
||||
tlb_lli_2m = 1024;
|
||||
} else {
|
||||
cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
|
||||
tlb_lli_2m[ENTRIES] = eax & 0xff;
|
||||
tlb_lli_2m = eax & 0xff;
|
||||
}
|
||||
} else
|
||||
tlb_lli_2m[ENTRIES] = eax & mask;
|
||||
tlb_lli_2m = eax & mask;
|
||||
|
||||
tlb_lli_4m[ENTRIES] = tlb_lli_2m[ENTRIES] >> 1;
|
||||
tlb_lli_4m = tlb_lli_2m >> 1;
|
||||
}
|
||||
|
||||
static const struct cpu_dev amd_cpu_dev = {
|
||||
|
||||
@@ -8,21 +8,19 @@
|
||||
* Andi Kleen / Andreas Herrmann : CPUID4 emulation on AMD.
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/cacheinfo.h>
|
||||
#include <linux/capability.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/cpuhotplug.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/capability.h>
|
||||
#include <linux/sysfs.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/stop_machine.h>
|
||||
#include <linux/sysfs.h>
|
||||
|
||||
#include <asm/cpufeature.h>
|
||||
#include <asm/cacheinfo.h>
|
||||
#include <asm/amd_nb.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/cacheinfo.h>
|
||||
#include <asm/cpufeature.h>
|
||||
#include <asm/mtrr.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
||||
#include "cpu.h"
|
||||
@@ -31,7 +29,6 @@
|
||||
#define LVL_1_DATA 2
|
||||
#define LVL_2 3
|
||||
#define LVL_3 4
|
||||
#define LVL_TRACE 5
|
||||
|
||||
/* Shared last level cache maps */
|
||||
DEFINE_PER_CPU_READ_MOSTLY(cpumask_var_t, cpu_llc_shared_map);
|
||||
@@ -96,10 +93,6 @@ static const struct _cache_table cache_table[] =
|
||||
{ 0x66, LVL_1_DATA, 8 }, /* 4-way set assoc, sectored cache, 64 byte line size */
|
||||
{ 0x67, LVL_1_DATA, 16 }, /* 4-way set assoc, sectored cache, 64 byte line size */
|
||||
{ 0x68, LVL_1_DATA, 32 }, /* 4-way set assoc, sectored cache, 64 byte line size */
|
||||
{ 0x70, LVL_TRACE, 12 }, /* 8-way set assoc */
|
||||
{ 0x71, LVL_TRACE, 16 }, /* 8-way set assoc */
|
||||
{ 0x72, LVL_TRACE, 32 }, /* 8-way set assoc */
|
||||
{ 0x73, LVL_TRACE, 64 }, /* 8-way set assoc */
|
||||
{ 0x78, LVL_2, MB(1) }, /* 4-way set assoc, 64 byte line size */
|
||||
{ 0x79, LVL_2, 128 }, /* 8-way set assoc, sectored cache, 64 byte line size */
|
||||
{ 0x7a, LVL_2, 256 }, /* 8-way set assoc, sectored cache, 64 byte line size */
|
||||
@@ -787,19 +780,13 @@ void init_intel_cacheinfo(struct cpuinfo_x86 *c)
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for
|
||||
* trace cache
|
||||
*/
|
||||
if ((!ci->num_leaves || c->x86 == 15) && c->cpuid_level > 1) {
|
||||
|
||||
/* Don't use CPUID(2) if CPUID(4) is supported. */
|
||||
if (!ci->num_leaves && c->cpuid_level > 1) {
|
||||
/* supports eax=2 call */
|
||||
int j, n;
|
||||
unsigned int regs[4];
|
||||
unsigned char *dp = (unsigned char *)regs;
|
||||
int only_trace = 0;
|
||||
|
||||
if (ci->num_leaves && c->x86 == 15)
|
||||
only_trace = 1;
|
||||
|
||||
/* Number of times to iterate */
|
||||
n = cpuid_eax(2) & 0xFF;
|
||||
@@ -808,7 +795,7 @@ void init_intel_cacheinfo(struct cpuinfo_x86 *c)
|
||||
cpuid(2, ®s[0], ®s[1], ®s[2], ®s[3]);
|
||||
|
||||
/* If bit 31 is set, this is an unknown format */
|
||||
for (j = 0 ; j < 3 ; j++)
|
||||
for (j = 0 ; j < 4 ; j++)
|
||||
if (regs[j] & (1 << 31))
|
||||
regs[j] = 0;
|
||||
|
||||
@@ -820,8 +807,6 @@ void init_intel_cacheinfo(struct cpuinfo_x86 *c)
|
||||
/* look up this descriptor in the table */
|
||||
while (cache_table[k].descriptor != 0) {
|
||||
if (cache_table[k].descriptor == des) {
|
||||
if (only_trace && cache_table[k].cache_type != LVL_TRACE)
|
||||
break;
|
||||
switch (cache_table[k].cache_type) {
|
||||
case LVL_1_INST:
|
||||
l1i += cache_table[k].size;
|
||||
|
||||
@@ -667,8 +667,8 @@ static void filter_cpuid_features(struct cpuinfo_x86 *c, bool warn)
|
||||
if (!warn)
|
||||
continue;
|
||||
|
||||
pr_warn("CPU: CPU feature " X86_CAP_FMT " disabled, no CPUID level 0x%x\n",
|
||||
x86_cap_flag(df->feature), df->level);
|
||||
pr_warn("CPU: CPU feature %s disabled, no CPUID level 0x%x\n",
|
||||
x86_cap_flags[df->feature], df->level);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -846,13 +846,13 @@ void cpu_detect_cache_sizes(struct cpuinfo_x86 *c)
|
||||
c->x86_cache_size = l2size;
|
||||
}
|
||||
|
||||
u16 __read_mostly tlb_lli_4k[NR_INFO];
|
||||
u16 __read_mostly tlb_lli_2m[NR_INFO];
|
||||
u16 __read_mostly tlb_lli_4m[NR_INFO];
|
||||
u16 __read_mostly tlb_lld_4k[NR_INFO];
|
||||
u16 __read_mostly tlb_lld_2m[NR_INFO];
|
||||
u16 __read_mostly tlb_lld_4m[NR_INFO];
|
||||
u16 __read_mostly tlb_lld_1g[NR_INFO];
|
||||
u16 __read_mostly tlb_lli_4k;
|
||||
u16 __read_mostly tlb_lli_2m;
|
||||
u16 __read_mostly tlb_lli_4m;
|
||||
u16 __read_mostly tlb_lld_4k;
|
||||
u16 __read_mostly tlb_lld_2m;
|
||||
u16 __read_mostly tlb_lld_4m;
|
||||
u16 __read_mostly tlb_lld_1g;
|
||||
|
||||
static void cpu_detect_tlb(struct cpuinfo_x86 *c)
|
||||
{
|
||||
@@ -860,12 +860,10 @@ static void cpu_detect_tlb(struct cpuinfo_x86 *c)
|
||||
this_cpu->c_detect_tlb(c);
|
||||
|
||||
pr_info("Last level iTLB entries: 4KB %d, 2MB %d, 4MB %d\n",
|
||||
tlb_lli_4k[ENTRIES], tlb_lli_2m[ENTRIES],
|
||||
tlb_lli_4m[ENTRIES]);
|
||||
tlb_lli_4k, tlb_lli_2m, tlb_lli_4m);
|
||||
|
||||
pr_info("Last level dTLB entries: 4KB %d, 2MB %d, 4MB %d, 1GB %d\n",
|
||||
tlb_lld_4k[ENTRIES], tlb_lld_2m[ENTRIES],
|
||||
tlb_lld_4m[ENTRIES], tlb_lld_1g[ENTRIES]);
|
||||
tlb_lld_4k, tlb_lld_2m, tlb_lld_4m, tlb_lld_1g);
|
||||
}
|
||||
|
||||
void get_cpu_vendor(struct cpuinfo_x86 *c)
|
||||
@@ -1164,7 +1162,7 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = {
|
||||
|
||||
VULNWL_INTEL(INTEL_CORE_YONAH, NO_SSB),
|
||||
|
||||
VULNWL_INTEL(INTEL_ATOM_AIRMONT_MID, NO_SSB | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | MSBDS_ONLY),
|
||||
VULNWL_INTEL(INTEL_ATOM_SILVERMONT_MID2,NO_SSB | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | MSBDS_ONLY),
|
||||
VULNWL_INTEL(INTEL_ATOM_AIRMONT_NP, NO_SSB | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT),
|
||||
|
||||
VULNWL_INTEL(INTEL_ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT | NO_MMIO),
|
||||
@@ -1479,15 +1477,96 @@ static void detect_nopl(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline bool parse_set_clear_cpuid(char *arg, bool set)
|
||||
{
|
||||
char *opt;
|
||||
int taint = 0;
|
||||
|
||||
while (arg) {
|
||||
bool found __maybe_unused = false;
|
||||
unsigned int bit;
|
||||
|
||||
opt = strsep(&arg, ",");
|
||||
|
||||
/*
|
||||
* Handle naked numbers first for feature flags which don't
|
||||
* have names. It doesn't make sense for a bug not to have a
|
||||
* name so don't handle bug flags here.
|
||||
*/
|
||||
if (!kstrtouint(opt, 10, &bit)) {
|
||||
if (bit < NCAPINTS * 32) {
|
||||
|
||||
if (set) {
|
||||
pr_warn("setcpuid: force-enabling CPU feature flag:");
|
||||
setup_force_cpu_cap(bit);
|
||||
} else {
|
||||
pr_warn("clearcpuid: force-disabling CPU feature flag:");
|
||||
setup_clear_cpu_cap(bit);
|
||||
}
|
||||
/* empty-string, i.e., ""-defined feature flags */
|
||||
if (!x86_cap_flags[bit])
|
||||
pr_cont(" %d:%d\n", bit >> 5, bit & 31);
|
||||
else
|
||||
pr_cont(" %s\n", x86_cap_flags[bit]);
|
||||
|
||||
taint++;
|
||||
}
|
||||
/*
|
||||
* The assumption is that there are no feature names with only
|
||||
* numbers in the name thus go to the next argument.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
for (bit = 0; bit < 32 * (NCAPINTS + NBUGINTS); bit++) {
|
||||
const char *flag;
|
||||
const char *kind;
|
||||
|
||||
if (bit < 32 * NCAPINTS) {
|
||||
flag = x86_cap_flags[bit];
|
||||
kind = "feature";
|
||||
} else {
|
||||
kind = "bug";
|
||||
flag = x86_bug_flags[bit - (32 * NCAPINTS)];
|
||||
}
|
||||
|
||||
if (!flag)
|
||||
continue;
|
||||
|
||||
if (strcmp(flag, opt))
|
||||
continue;
|
||||
|
||||
if (set) {
|
||||
pr_warn("setcpuid: force-enabling CPU %s flag: %s\n",
|
||||
kind, flag);
|
||||
setup_force_cpu_cap(bit);
|
||||
} else {
|
||||
pr_warn("clearcpuid: force-disabling CPU %s flag: %s\n",
|
||||
kind, flag);
|
||||
setup_clear_cpu_cap(bit);
|
||||
}
|
||||
taint++;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
pr_warn("%s: unknown CPU flag: %s", set ? "setcpuid" : "clearcpuid", opt);
|
||||
}
|
||||
|
||||
return taint;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* We parse cpu parameters early because fpu__init_system() is executed
|
||||
* before parse_early_param().
|
||||
*/
|
||||
static void __init cpu_parse_early_param(void)
|
||||
{
|
||||
bool cpuid_taint = false;
|
||||
char arg[128];
|
||||
char *argptr = arg, *opt;
|
||||
int arglen, taint = 0;
|
||||
int arglen;
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
if (cmdline_find_option_bool(boot_command_line, "no387"))
|
||||
@@ -1519,61 +1598,17 @@ static void __init cpu_parse_early_param(void)
|
||||
setup_clear_cpu_cap(X86_FEATURE_FRED);
|
||||
|
||||
arglen = cmdline_find_option(boot_command_line, "clearcpuid", arg, sizeof(arg));
|
||||
if (arglen <= 0)
|
||||
return;
|
||||
if (arglen > 0)
|
||||
cpuid_taint |= parse_set_clear_cpuid(arg, false);
|
||||
|
||||
pr_info("Clearing CPUID bits:");
|
||||
arglen = cmdline_find_option(boot_command_line, "setcpuid", arg, sizeof(arg));
|
||||
if (arglen > 0)
|
||||
cpuid_taint |= parse_set_clear_cpuid(arg, true);
|
||||
|
||||
while (argptr) {
|
||||
bool found __maybe_unused = false;
|
||||
unsigned int bit;
|
||||
|
||||
opt = strsep(&argptr, ",");
|
||||
|
||||
/*
|
||||
* Handle naked numbers first for feature flags which don't
|
||||
* have names.
|
||||
*/
|
||||
if (!kstrtouint(opt, 10, &bit)) {
|
||||
if (bit < NCAPINTS * 32) {
|
||||
|
||||
/* empty-string, i.e., ""-defined feature flags */
|
||||
if (!x86_cap_flags[bit])
|
||||
pr_cont(" " X86_CAP_FMT_NUM, x86_cap_flag_num(bit));
|
||||
else
|
||||
pr_cont(" " X86_CAP_FMT, x86_cap_flag(bit));
|
||||
|
||||
setup_clear_cpu_cap(bit);
|
||||
taint++;
|
||||
}
|
||||
/*
|
||||
* The assumption is that there are no feature names with only
|
||||
* numbers in the name thus go to the next argument.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
for (bit = 0; bit < 32 * NCAPINTS; bit++) {
|
||||
if (!x86_cap_flag(bit))
|
||||
continue;
|
||||
|
||||
if (strcmp(x86_cap_flag(bit), opt))
|
||||
continue;
|
||||
|
||||
pr_cont(" %s", opt);
|
||||
setup_clear_cpu_cap(bit);
|
||||
taint++;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
pr_cont(" (unknown: %s)", opt);
|
||||
}
|
||||
pr_cont("\n");
|
||||
|
||||
if (taint)
|
||||
if (cpuid_taint) {
|
||||
pr_warn("!!! setcpuid=/clearcpuid= in use, this is for TESTING ONLY, may break things horribly. Tainting kernel.\n");
|
||||
add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1962,9 +1997,15 @@ static __init void identify_boot_cpu(void)
|
||||
lkgs_init();
|
||||
}
|
||||
|
||||
void identify_secondary_cpu(struct cpuinfo_x86 *c)
|
||||
void identify_secondary_cpu(unsigned int cpu)
|
||||
{
|
||||
BUG_ON(c == &boot_cpu_data);
|
||||
struct cpuinfo_x86 *c = &cpu_data(cpu);
|
||||
|
||||
/* Copy boot_cpu_data only on the first bringup */
|
||||
if (!c->initialized)
|
||||
*c = boot_cpu_data;
|
||||
c->cpu_index = cpu;
|
||||
|
||||
identify_cpu(c);
|
||||
#ifdef CONFIG_X86_32
|
||||
enable_sep_cpu();
|
||||
@@ -1975,6 +2016,7 @@ void identify_secondary_cpu(struct cpuinfo_x86 *c)
|
||||
update_gds_msr();
|
||||
|
||||
tsx_ap_init();
|
||||
c->initialized = true;
|
||||
}
|
||||
|
||||
void print_cpu_info(struct cpuinfo_x86 *c)
|
||||
@@ -2005,15 +2047,23 @@ void print_cpu_info(struct cpuinfo_x86 *c)
|
||||
}
|
||||
|
||||
/*
|
||||
* clearcpuid= was already parsed in cpu_parse_early_param(). This dummy
|
||||
* function prevents it from becoming an environment variable for init.
|
||||
* clearcpuid= and setcpuid= were already parsed in cpu_parse_early_param().
|
||||
* These dummy functions prevent them from becoming an environment variable for
|
||||
* init.
|
||||
*/
|
||||
|
||||
static __init int setup_clearcpuid(char *arg)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
__setup("clearcpuid=", setup_clearcpuid);
|
||||
|
||||
static __init int setup_setcpuid(char *arg)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
__setup("setcpuid=", setup_setcpuid);
|
||||
|
||||
DEFINE_PER_CPU_ALIGNED(struct pcpu_hot, pcpu_hot) = {
|
||||
.current_task = &init_task,
|
||||
.preempt_count = INIT_PREEMPT_COUNT,
|
||||
@@ -2023,10 +2073,6 @@ EXPORT_PER_CPU_SYMBOL(pcpu_hot);
|
||||
EXPORT_PER_CPU_SYMBOL(const_pcpu_hot);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
DEFINE_PER_CPU_FIRST(struct fixed_percpu_data,
|
||||
fixed_percpu_data) __aligned(PAGE_SIZE) __visible;
|
||||
EXPORT_PER_CPU_SYMBOL_GPL(fixed_percpu_data);
|
||||
|
||||
static void wrmsrl_cstar(unsigned long val)
|
||||
{
|
||||
/*
|
||||
@@ -2089,8 +2135,7 @@ void syscall_init(void)
|
||||
if (!cpu_feature_enabled(X86_FEATURE_FRED))
|
||||
idt_syscall_init();
|
||||
}
|
||||
|
||||
#else /* CONFIG_X86_64 */
|
||||
#endif /* CONFIG_X86_64 */
|
||||
|
||||
#ifdef CONFIG_STACKPROTECTOR
|
||||
DEFINE_PER_CPU(unsigned long, __stack_chk_guard);
|
||||
@@ -2099,8 +2144,6 @@ EXPORT_PER_CPU_SYMBOL(__stack_chk_guard);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_X86_64 */
|
||||
|
||||
/*
|
||||
* Clear all 6 debug registers:
|
||||
*/
|
||||
|
||||
@@ -33,14 +33,6 @@ struct cpu_dev {
|
||||
#endif
|
||||
};
|
||||
|
||||
struct _tlb_table {
|
||||
unsigned char descriptor;
|
||||
char tlb_type;
|
||||
unsigned int entries;
|
||||
/* unsigned int ways; */
|
||||
char info[128];
|
||||
};
|
||||
|
||||
#define cpu_dev_register(cpu_devX) \
|
||||
static const struct cpu_dev *const __cpu_dev_##cpu_devX __used \
|
||||
__section(".x86_cpu_dev.init") = \
|
||||
|
||||
@@ -16,8 +16,8 @@ static int cpu_debug_show(struct seq_file *m, void *p)
|
||||
if (!c->initialized)
|
||||
return 0;
|
||||
|
||||
seq_printf(m, "initial_apicid: %x\n", c->topo.initial_apicid);
|
||||
seq_printf(m, "apicid: %x\n", c->topo.apicid);
|
||||
seq_printf(m, "initial_apicid: 0x%x\n", c->topo.initial_apicid);
|
||||
seq_printf(m, "apicid: 0x%x\n", c->topo.apicid);
|
||||
seq_printf(m, "pkg_id: %u\n", c->topo.pkg_id);
|
||||
seq_printf(m, "die_id: %u\n", c->topo.die_id);
|
||||
seq_printf(m, "cu_id: %u\n", c->topo.cu_id);
|
||||
|
||||
@@ -240,26 +240,26 @@ static void cpu_detect_tlb_hygon(struct cpuinfo_x86 *c)
|
||||
|
||||
cpuid(0x80000006, &eax, &ebx, &ecx, &edx);
|
||||
|
||||
tlb_lld_4k[ENTRIES] = (ebx >> 16) & mask;
|
||||
tlb_lli_4k[ENTRIES] = ebx & mask;
|
||||
tlb_lld_4k = (ebx >> 16) & mask;
|
||||
tlb_lli_4k = ebx & mask;
|
||||
|
||||
/* Handle DTLB 2M and 4M sizes, fall back to L1 if L2 is disabled */
|
||||
if (!((eax >> 16) & mask))
|
||||
tlb_lld_2m[ENTRIES] = (cpuid_eax(0x80000005) >> 16) & 0xff;
|
||||
tlb_lld_2m = (cpuid_eax(0x80000005) >> 16) & 0xff;
|
||||
else
|
||||
tlb_lld_2m[ENTRIES] = (eax >> 16) & mask;
|
||||
tlb_lld_2m = (eax >> 16) & mask;
|
||||
|
||||
/* a 4M entry uses two 2M entries */
|
||||
tlb_lld_4m[ENTRIES] = tlb_lld_2m[ENTRIES] >> 1;
|
||||
tlb_lld_4m = tlb_lld_2m >> 1;
|
||||
|
||||
/* Handle ITLB 2M and 4M sizes, fall back to L1 if L2 is disabled */
|
||||
if (!(eax & mask)) {
|
||||
cpuid(0x80000005, &eax, &ebx, &ecx, &edx);
|
||||
tlb_lli_2m[ENTRIES] = eax & 0xff;
|
||||
tlb_lli_2m = eax & 0xff;
|
||||
} else
|
||||
tlb_lli_2m[ENTRIES] = eax & mask;
|
||||
tlb_lli_2m = eax & mask;
|
||||
|
||||
tlb_lli_4m[ENTRIES] = tlb_lli_2m[ENTRIES] >> 1;
|
||||
tlb_lli_4m = tlb_lli_2m >> 1;
|
||||
}
|
||||
|
||||
static const struct cpu_dev hygon_cpu_dev = {
|
||||
|
||||
@@ -1,39 +1,30 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pgtable.h>
|
||||
|
||||
#include <linux/string.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/sched/clock.h>
|
||||
#include <linux/thread_info.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <asm/cpufeature.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/bugs.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/intel-family.h>
|
||||
#include <asm/microcode.h>
|
||||
#include <asm/hwcap2.h>
|
||||
#include <asm/elf.h>
|
||||
#include <asm/cpu_device_id.h>
|
||||
#include <asm/resctrl.h>
|
||||
#include <asm/numa.h>
|
||||
#include <asm/thermal.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/minmax.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
#include <linux/topology.h>
|
||||
#endif
|
||||
|
||||
#include "cpu.h"
|
||||
#include <asm/bugs.h>
|
||||
#include <asm/cpu_device_id.h>
|
||||
#include <asm/cpufeature.h>
|
||||
#include <asm/cpu.h>
|
||||
#include <asm/hwcap2.h>
|
||||
#include <asm/intel-family.h>
|
||||
#include <asm/microcode.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/numa.h>
|
||||
#include <asm/resctrl.h>
|
||||
#include <asm/thermal.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
#include <asm/mpspec.h>
|
||||
#include <asm/apic.h>
|
||||
#endif
|
||||
#include "cpu.h"
|
||||
|
||||
/*
|
||||
* Processors which have self-snooping capability can handle conflicting
|
||||
@@ -635,70 +626,90 @@ static unsigned int intel_size_cache(struct cpuinfo_x86 *c, unsigned int size)
|
||||
}
|
||||
#endif
|
||||
|
||||
#define TLB_INST_4K 0x01
|
||||
#define TLB_INST_4M 0x02
|
||||
#define TLB_INST_2M_4M 0x03
|
||||
#define TLB_INST_4K 0x01
|
||||
#define TLB_INST_4M 0x02
|
||||
#define TLB_INST_2M_4M 0x03
|
||||
|
||||
#define TLB_INST_ALL 0x05
|
||||
#define TLB_INST_1G 0x06
|
||||
#define TLB_INST_ALL 0x05
|
||||
#define TLB_INST_1G 0x06
|
||||
|
||||
#define TLB_DATA_4K 0x11
|
||||
#define TLB_DATA_4M 0x12
|
||||
#define TLB_DATA_2M_4M 0x13
|
||||
#define TLB_DATA_4K_4M 0x14
|
||||
#define TLB_DATA_4K 0x11
|
||||
#define TLB_DATA_4M 0x12
|
||||
#define TLB_DATA_2M_4M 0x13
|
||||
#define TLB_DATA_4K_4M 0x14
|
||||
|
||||
#define TLB_DATA_1G 0x16
|
||||
#define TLB_DATA_1G 0x16
|
||||
#define TLB_DATA_1G_2M_4M 0x17
|
||||
|
||||
#define TLB_DATA0_4K 0x21
|
||||
#define TLB_DATA0_4M 0x22
|
||||
#define TLB_DATA0_2M_4M 0x23
|
||||
#define TLB_DATA0_4K 0x21
|
||||
#define TLB_DATA0_4M 0x22
|
||||
#define TLB_DATA0_2M_4M 0x23
|
||||
|
||||
#define STLB_4K 0x41
|
||||
#define STLB_4K_2M 0x42
|
||||
#define STLB_4K 0x41
|
||||
#define STLB_4K_2M 0x42
|
||||
|
||||
/*
|
||||
* All of leaf 0x2's one-byte TLB descriptors implies the same number of
|
||||
* entries for their respective TLB types. The 0x63 descriptor is an
|
||||
* exception: it implies 4 dTLB entries for 1GB pages 32 dTLB entries
|
||||
* for 2MB or 4MB pages. Encode descriptor 0x63 dTLB entry count for
|
||||
* 2MB/4MB pages here, as its count for dTLB 1GB pages is already at the
|
||||
* intel_tlb_table[] mapping.
|
||||
*/
|
||||
#define TLB_0x63_2M_4M_ENTRIES 32
|
||||
|
||||
struct _tlb_table {
|
||||
unsigned char descriptor;
|
||||
char tlb_type;
|
||||
unsigned int entries;
|
||||
};
|
||||
|
||||
static const struct _tlb_table intel_tlb_table[] = {
|
||||
{ 0x01, TLB_INST_4K, 32, " TLB_INST 4 KByte pages, 4-way set associative" },
|
||||
{ 0x02, TLB_INST_4M, 2, " TLB_INST 4 MByte pages, full associative" },
|
||||
{ 0x03, TLB_DATA_4K, 64, " TLB_DATA 4 KByte pages, 4-way set associative" },
|
||||
{ 0x04, TLB_DATA_4M, 8, " TLB_DATA 4 MByte pages, 4-way set associative" },
|
||||
{ 0x05, TLB_DATA_4M, 32, " TLB_DATA 4 MByte pages, 4-way set associative" },
|
||||
{ 0x0b, TLB_INST_4M, 4, " TLB_INST 4 MByte pages, 4-way set associative" },
|
||||
{ 0x4f, TLB_INST_4K, 32, " TLB_INST 4 KByte pages" },
|
||||
{ 0x50, TLB_INST_ALL, 64, " TLB_INST 4 KByte and 2-MByte or 4-MByte pages" },
|
||||
{ 0x51, TLB_INST_ALL, 128, " TLB_INST 4 KByte and 2-MByte or 4-MByte pages" },
|
||||
{ 0x52, TLB_INST_ALL, 256, " TLB_INST 4 KByte and 2-MByte or 4-MByte pages" },
|
||||
{ 0x55, TLB_INST_2M_4M, 7, " TLB_INST 2-MByte or 4-MByte pages, fully associative" },
|
||||
{ 0x56, TLB_DATA0_4M, 16, " TLB_DATA0 4 MByte pages, 4-way set associative" },
|
||||
{ 0x57, TLB_DATA0_4K, 16, " TLB_DATA0 4 KByte pages, 4-way associative" },
|
||||
{ 0x59, TLB_DATA0_4K, 16, " TLB_DATA0 4 KByte pages, fully associative" },
|
||||
{ 0x5a, TLB_DATA0_2M_4M, 32, " TLB_DATA0 2-MByte or 4 MByte pages, 4-way set associative" },
|
||||
{ 0x5b, TLB_DATA_4K_4M, 64, " TLB_DATA 4 KByte and 4 MByte pages" },
|
||||
{ 0x5c, TLB_DATA_4K_4M, 128, " TLB_DATA 4 KByte and 4 MByte pages" },
|
||||
{ 0x5d, TLB_DATA_4K_4M, 256, " TLB_DATA 4 KByte and 4 MByte pages" },
|
||||
{ 0x61, TLB_INST_4K, 48, " TLB_INST 4 KByte pages, full associative" },
|
||||
{ 0x63, TLB_DATA_1G, 4, " TLB_DATA 1 GByte pages, 4-way set associative" },
|
||||
{ 0x6b, TLB_DATA_4K, 256, " TLB_DATA 4 KByte pages, 8-way associative" },
|
||||
{ 0x6c, TLB_DATA_2M_4M, 128, " TLB_DATA 2 MByte or 4 MByte pages, 8-way associative" },
|
||||
{ 0x6d, TLB_DATA_1G, 16, " TLB_DATA 1 GByte pages, fully associative" },
|
||||
{ 0x76, TLB_INST_2M_4M, 8, " TLB_INST 2-MByte or 4-MByte pages, fully associative" },
|
||||
{ 0xb0, TLB_INST_4K, 128, " TLB_INST 4 KByte pages, 4-way set associative" },
|
||||
{ 0xb1, TLB_INST_2M_4M, 4, " TLB_INST 2M pages, 4-way, 8 entries or 4M pages, 4-way entries" },
|
||||
{ 0xb2, TLB_INST_4K, 64, " TLB_INST 4KByte pages, 4-way set associative" },
|
||||
{ 0xb3, TLB_DATA_4K, 128, " TLB_DATA 4 KByte pages, 4-way set associative" },
|
||||
{ 0xb4, TLB_DATA_4K, 256, " TLB_DATA 4 KByte pages, 4-way associative" },
|
||||
{ 0xb5, TLB_INST_4K, 64, " TLB_INST 4 KByte pages, 8-way set associative" },
|
||||
{ 0xb6, TLB_INST_4K, 128, " TLB_INST 4 KByte pages, 8-way set associative" },
|
||||
{ 0xba, TLB_DATA_4K, 64, " TLB_DATA 4 KByte pages, 4-way associative" },
|
||||
{ 0xc0, TLB_DATA_4K_4M, 8, " TLB_DATA 4 KByte and 4 MByte pages, 4-way associative" },
|
||||
{ 0xc1, STLB_4K_2M, 1024, " STLB 4 KByte and 2 MByte pages, 8-way associative" },
|
||||
{ 0xc2, TLB_DATA_2M_4M, 16, " TLB_DATA 2 MByte/4MByte pages, 4-way associative" },
|
||||
{ 0xca, STLB_4K, 512, " STLB 4 KByte pages, 4-way associative" },
|
||||
{ 0x01, TLB_INST_4K, 32}, /* TLB_INST 4 KByte pages, 4-way set associative */
|
||||
{ 0x02, TLB_INST_4M, 2}, /* TLB_INST 4 MByte pages, full associative */
|
||||
{ 0x03, TLB_DATA_4K, 64}, /* TLB_DATA 4 KByte pages, 4-way set associative */
|
||||
{ 0x04, TLB_DATA_4M, 8}, /* TLB_DATA 4 MByte pages, 4-way set associative */
|
||||
{ 0x05, TLB_DATA_4M, 32}, /* TLB_DATA 4 MByte pages, 4-way set associative */
|
||||
{ 0x0b, TLB_INST_4M, 4}, /* TLB_INST 4 MByte pages, 4-way set associative */
|
||||
{ 0x4f, TLB_INST_4K, 32}, /* TLB_INST 4 KByte pages */
|
||||
{ 0x50, TLB_INST_ALL, 64}, /* TLB_INST 4 KByte and 2-MByte or 4-MByte pages */
|
||||
{ 0x51, TLB_INST_ALL, 128}, /* TLB_INST 4 KByte and 2-MByte or 4-MByte pages */
|
||||
{ 0x52, TLB_INST_ALL, 256}, /* TLB_INST 4 KByte and 2-MByte or 4-MByte pages */
|
||||
{ 0x55, TLB_INST_2M_4M, 7}, /* TLB_INST 2-MByte or 4-MByte pages, fully associative */
|
||||
{ 0x56, TLB_DATA0_4M, 16}, /* TLB_DATA0 4 MByte pages, 4-way set associative */
|
||||
{ 0x57, TLB_DATA0_4K, 16}, /* TLB_DATA0 4 KByte pages, 4-way associative */
|
||||
{ 0x59, TLB_DATA0_4K, 16}, /* TLB_DATA0 4 KByte pages, fully associative */
|
||||
{ 0x5a, TLB_DATA0_2M_4M, 32}, /* TLB_DATA0 2-MByte or 4 MByte pages, 4-way set associative */
|
||||
{ 0x5b, TLB_DATA_4K_4M, 64}, /* TLB_DATA 4 KByte and 4 MByte pages */
|
||||
{ 0x5c, TLB_DATA_4K_4M, 128}, /* TLB_DATA 4 KByte and 4 MByte pages */
|
||||
{ 0x5d, TLB_DATA_4K_4M, 256}, /* TLB_DATA 4 KByte and 4 MByte pages */
|
||||
{ 0x61, TLB_INST_4K, 48}, /* TLB_INST 4 KByte pages, full associative */
|
||||
{ 0x63, TLB_DATA_1G_2M_4M, 4}, /* TLB_DATA 1 GByte pages, 4-way set associative
|
||||
* (plus 32 entries TLB_DATA 2 MByte or 4 MByte pages, not encoded here) */
|
||||
{ 0x6b, TLB_DATA_4K, 256}, /* TLB_DATA 4 KByte pages, 8-way associative */
|
||||
{ 0x6c, TLB_DATA_2M_4M, 128}, /* TLB_DATA 2 MByte or 4 MByte pages, 8-way associative */
|
||||
{ 0x6d, TLB_DATA_1G, 16}, /* TLB_DATA 1 GByte pages, fully associative */
|
||||
{ 0x76, TLB_INST_2M_4M, 8}, /* TLB_INST 2-MByte or 4-MByte pages, fully associative */
|
||||
{ 0xb0, TLB_INST_4K, 128}, /* TLB_INST 4 KByte pages, 4-way set associative */
|
||||
{ 0xb1, TLB_INST_2M_4M, 4}, /* TLB_INST 2M pages, 4-way, 8 entries or 4M pages, 4-way entries */
|
||||
{ 0xb2, TLB_INST_4K, 64}, /* TLB_INST 4KByte pages, 4-way set associative */
|
||||
{ 0xb3, TLB_DATA_4K, 128}, /* TLB_DATA 4 KByte pages, 4-way set associative */
|
||||
{ 0xb4, TLB_DATA_4K, 256}, /* TLB_DATA 4 KByte pages, 4-way associative */
|
||||
{ 0xb5, TLB_INST_4K, 64}, /* TLB_INST 4 KByte pages, 8-way set associative */
|
||||
{ 0xb6, TLB_INST_4K, 128}, /* TLB_INST 4 KByte pages, 8-way set associative */
|
||||
{ 0xba, TLB_DATA_4K, 64}, /* TLB_DATA 4 KByte pages, 4-way associative */
|
||||
{ 0xc0, TLB_DATA_4K_4M, 8}, /* TLB_DATA 4 KByte and 4 MByte pages, 4-way associative */
|
||||
{ 0xc1, STLB_4K_2M, 1024}, /* STLB 4 KByte and 2 MByte pages, 8-way associative */
|
||||
{ 0xc2, TLB_DATA_2M_4M, 16}, /* TLB_DATA 2 MByte/4MByte pages, 4-way associative */
|
||||
{ 0xca, STLB_4K, 512}, /* STLB 4 KByte pages, 4-way associative */
|
||||
{ 0x00, 0, 0 }
|
||||
};
|
||||
|
||||
static void intel_tlb_lookup(const unsigned char desc)
|
||||
{
|
||||
unsigned int entries;
|
||||
unsigned char k;
|
||||
|
||||
if (desc == 0)
|
||||
return;
|
||||
|
||||
@@ -710,75 +721,58 @@ static void intel_tlb_lookup(const unsigned char desc)
|
||||
if (intel_tlb_table[k].tlb_type == 0)
|
||||
return;
|
||||
|
||||
entries = intel_tlb_table[k].entries;
|
||||
switch (intel_tlb_table[k].tlb_type) {
|
||||
case STLB_4K:
|
||||
if (tlb_lli_4k[ENTRIES] < intel_tlb_table[k].entries)
|
||||
tlb_lli_4k[ENTRIES] = intel_tlb_table[k].entries;
|
||||
if (tlb_lld_4k[ENTRIES] < intel_tlb_table[k].entries)
|
||||
tlb_lld_4k[ENTRIES] = intel_tlb_table[k].entries;
|
||||
tlb_lli_4k = max(tlb_lli_4k, entries);
|
||||
tlb_lld_4k = max(tlb_lld_4k, entries);
|
||||
break;
|
||||
case STLB_4K_2M:
|
||||
if (tlb_lli_4k[ENTRIES] < intel_tlb_table[k].entries)
|
||||
tlb_lli_4k[ENTRIES] = intel_tlb_table[k].entries;
|
||||
if (tlb_lld_4k[ENTRIES] < intel_tlb_table[k].entries)
|
||||
tlb_lld_4k[ENTRIES] = intel_tlb_table[k].entries;
|
||||
if (tlb_lli_2m[ENTRIES] < intel_tlb_table[k].entries)
|
||||
tlb_lli_2m[ENTRIES] = intel_tlb_table[k].entries;
|
||||
if (tlb_lld_2m[ENTRIES] < intel_tlb_table[k].entries)
|
||||
tlb_lld_2m[ENTRIES] = intel_tlb_table[k].entries;
|
||||
if (tlb_lli_4m[ENTRIES] < intel_tlb_table[k].entries)
|
||||
tlb_lli_4m[ENTRIES] = intel_tlb_table[k].entries;
|
||||
if (tlb_lld_4m[ENTRIES] < intel_tlb_table[k].entries)
|
||||
tlb_lld_4m[ENTRIES] = intel_tlb_table[k].entries;
|
||||
tlb_lli_4k = max(tlb_lli_4k, entries);
|
||||
tlb_lld_4k = max(tlb_lld_4k, entries);
|
||||
tlb_lli_2m = max(tlb_lli_2m, entries);
|
||||
tlb_lld_2m = max(tlb_lld_2m, entries);
|
||||
tlb_lli_4m = max(tlb_lli_4m, entries);
|
||||
tlb_lld_4m = max(tlb_lld_4m, entries);
|
||||
break;
|
||||
case TLB_INST_ALL:
|
||||
if (tlb_lli_4k[ENTRIES] < intel_tlb_table[k].entries)
|
||||
tlb_lli_4k[ENTRIES] = intel_tlb_table[k].entries;
|
||||
if (tlb_lli_2m[ENTRIES] < intel_tlb_table[k].entries)
|
||||
tlb_lli_2m[ENTRIES] = intel_tlb_table[k].entries;
|
||||
if (tlb_lli_4m[ENTRIES] < intel_tlb_table[k].entries)
|
||||
tlb_lli_4m[ENTRIES] = intel_tlb_table[k].entries;
|
||||
tlb_lli_4k = max(tlb_lli_4k, entries);
|
||||
tlb_lli_2m = max(tlb_lli_2m, entries);
|
||||
tlb_lli_4m = max(tlb_lli_4m, entries);
|
||||
break;
|
||||
case TLB_INST_4K:
|
||||
if (tlb_lli_4k[ENTRIES] < intel_tlb_table[k].entries)
|
||||
tlb_lli_4k[ENTRIES] = intel_tlb_table[k].entries;
|
||||
tlb_lli_4k = max(tlb_lli_4k, entries);
|
||||
break;
|
||||
case TLB_INST_4M:
|
||||
if (tlb_lli_4m[ENTRIES] < intel_tlb_table[k].entries)
|
||||
tlb_lli_4m[ENTRIES] = intel_tlb_table[k].entries;
|
||||
tlb_lli_4m = max(tlb_lli_4m, entries);
|
||||
break;
|
||||
case TLB_INST_2M_4M:
|
||||
if (tlb_lli_2m[ENTRIES] < intel_tlb_table[k].entries)
|
||||
tlb_lli_2m[ENTRIES] = intel_tlb_table[k].entries;
|
||||
if (tlb_lli_4m[ENTRIES] < intel_tlb_table[k].entries)
|
||||
tlb_lli_4m[ENTRIES] = intel_tlb_table[k].entries;
|
||||
tlb_lli_2m = max(tlb_lli_2m, entries);
|
||||
tlb_lli_4m = max(tlb_lli_4m, entries);
|
||||
break;
|
||||
case TLB_DATA_4K:
|
||||
case TLB_DATA0_4K:
|
||||
if (tlb_lld_4k[ENTRIES] < intel_tlb_table[k].entries)
|
||||
tlb_lld_4k[ENTRIES] = intel_tlb_table[k].entries;
|
||||
tlb_lld_4k = max(tlb_lld_4k, entries);
|
||||
break;
|
||||
case TLB_DATA_4M:
|
||||
case TLB_DATA0_4M:
|
||||
if (tlb_lld_4m[ENTRIES] < intel_tlb_table[k].entries)
|
||||
tlb_lld_4m[ENTRIES] = intel_tlb_table[k].entries;
|
||||
tlb_lld_4m = max(tlb_lld_4m, entries);
|
||||
break;
|
||||
case TLB_DATA_2M_4M:
|
||||
case TLB_DATA0_2M_4M:
|
||||
if (tlb_lld_2m[ENTRIES] < intel_tlb_table[k].entries)
|
||||
tlb_lld_2m[ENTRIES] = intel_tlb_table[k].entries;
|
||||
if (tlb_lld_4m[ENTRIES] < intel_tlb_table[k].entries)
|
||||
tlb_lld_4m[ENTRIES] = intel_tlb_table[k].entries;
|
||||
tlb_lld_2m = max(tlb_lld_2m, entries);
|
||||
tlb_lld_4m = max(tlb_lld_4m, entries);
|
||||
break;
|
||||
case TLB_DATA_4K_4M:
|
||||
if (tlb_lld_4k[ENTRIES] < intel_tlb_table[k].entries)
|
||||
tlb_lld_4k[ENTRIES] = intel_tlb_table[k].entries;
|
||||
if (tlb_lld_4m[ENTRIES] < intel_tlb_table[k].entries)
|
||||
tlb_lld_4m[ENTRIES] = intel_tlb_table[k].entries;
|
||||
tlb_lld_4k = max(tlb_lld_4k, entries);
|
||||
tlb_lld_4m = max(tlb_lld_4m, entries);
|
||||
break;
|
||||
case TLB_DATA_1G_2M_4M:
|
||||
tlb_lld_2m = max(tlb_lld_2m, TLB_0x63_2M_4M_ENTRIES);
|
||||
tlb_lld_4m = max(tlb_lld_4m, TLB_0x63_2M_4M_ENTRIES);
|
||||
fallthrough;
|
||||
case TLB_DATA_1G:
|
||||
if (tlb_lld_1g[ENTRIES] < intel_tlb_table[k].entries)
|
||||
tlb_lld_1g[ENTRIES] = intel_tlb_table[k].entries;
|
||||
tlb_lld_1g = max(tlb_lld_1g, entries);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -799,7 +793,7 @@ static void intel_detect_tlb(struct cpuinfo_x86 *c)
|
||||
cpuid(2, ®s[0], ®s[1], ®s[2], ®s[3]);
|
||||
|
||||
/* If bit 31 is set, this is an unknown format */
|
||||
for (j = 0 ; j < 3 ; j++)
|
||||
for (j = 0 ; j < 4 ; j++)
|
||||
if (regs[j] & (1 << 31))
|
||||
regs[j] = 0;
|
||||
|
||||
@@ -873,34 +867,3 @@ static const struct cpu_dev intel_cpu_dev = {
|
||||
};
|
||||
|
||||
cpu_dev_register(intel_cpu_dev);
|
||||
|
||||
#define X86_HYBRID_CPU_TYPE_ID_SHIFT 24
|
||||
|
||||
/**
|
||||
* get_this_hybrid_cpu_type() - Get the type of this hybrid CPU
|
||||
*
|
||||
* Returns the CPU type [31:24] (i.e., Atom or Core) of a CPU in
|
||||
* a hybrid processor. If the processor is not hybrid, returns 0.
|
||||
*/
|
||||
u8 get_this_hybrid_cpu_type(void)
|
||||
{
|
||||
if (!cpu_feature_enabled(X86_FEATURE_HYBRID_CPU))
|
||||
return 0;
|
||||
|
||||
return cpuid_eax(0x0000001a) >> X86_HYBRID_CPU_TYPE_ID_SHIFT;
|
||||
}
|
||||
|
||||
/**
|
||||
* get_this_hybrid_cpu_native_id() - Get the native id of this hybrid CPU
|
||||
*
|
||||
* Returns the uarch native ID [23:0] of a CPU in a hybrid processor.
|
||||
* If the processor is not hybrid, returns 0.
|
||||
*/
|
||||
u32 get_this_hybrid_cpu_native_id(void)
|
||||
{
|
||||
if (!cpu_feature_enabled(X86_FEATURE_HYBRID_CPU))
|
||||
return 0;
|
||||
|
||||
return cpuid_eax(0x0000001a) &
|
||||
(BIT_ULL(X86_HYBRID_CPU_TYPE_ID_SHIFT) - 1);
|
||||
}
|
||||
|
||||
@@ -99,7 +99,6 @@ mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos)
|
||||
char *ptr;
|
||||
char line[LINE_SIZE];
|
||||
int length;
|
||||
size_t linelen;
|
||||
|
||||
memset(line, 0, LINE_SIZE);
|
||||
|
||||
@@ -108,9 +107,8 @@ mtrr_write(struct file *file, const char __user *buf, size_t len, loff_t * ppos)
|
||||
if (length < 0)
|
||||
return length;
|
||||
|
||||
linelen = strlen(line);
|
||||
ptr = line + linelen - 1;
|
||||
if (linelen && *ptr == '\n')
|
||||
ptr = line + length - 1;
|
||||
if (length && *ptr == '\n')
|
||||
*ptr = '\0';
|
||||
|
||||
if (!strncmp(line, "disable=", 8)) {
|
||||
|
||||
@@ -567,7 +567,7 @@ void early_setup_idt(void)
|
||||
*/
|
||||
void __head startup_64_setup_gdt_idt(void)
|
||||
{
|
||||
struct desc_struct *gdt = (void *)(__force unsigned long)init_per_cpu_var(gdt_page.gdt);
|
||||
struct desc_struct *gdt = (void *)(__force unsigned long)gdt_page.gdt;
|
||||
void *handler = NULL;
|
||||
|
||||
struct desc_ptr startup_gdt_descr = {
|
||||
|
||||
@@ -61,11 +61,14 @@ SYM_CODE_START_NOALIGN(startup_64)
|
||||
/* Set up the stack for verify_cpu() */
|
||||
leaq __top_init_kernel_stack(%rip), %rsp
|
||||
|
||||
/* Setup GSBASE to allow stack canary access for C code */
|
||||
/*
|
||||
* Set up GSBASE.
|
||||
* Note that on SMP the boot CPU uses the init data section until
|
||||
* the per-CPU areas are set up.
|
||||
*/
|
||||
movl $MSR_GS_BASE, %ecx
|
||||
leaq INIT_PER_CPU_VAR(fixed_percpu_data)(%rip), %rdx
|
||||
movl %edx, %eax
|
||||
shrq $32, %rdx
|
||||
xorl %eax, %eax
|
||||
xorl %edx, %edx
|
||||
wrmsr
|
||||
|
||||
call startup_64_setup_gdt_idt
|
||||
@@ -359,17 +362,12 @@ SYM_INNER_LABEL(common_startup_64, SYM_L_LOCAL)
|
||||
movl %eax,%fs
|
||||
movl %eax,%gs
|
||||
|
||||
/* Set up %gs.
|
||||
*
|
||||
* The base of %gs always points to fixed_percpu_data. If the
|
||||
* stack protector canary is enabled, it is located at %gs:40.
|
||||
/*
|
||||
* Set up GSBASE.
|
||||
* Note that, on SMP, the boot cpu uses init data section until
|
||||
* the per cpu areas are set up.
|
||||
*/
|
||||
movl $MSR_GS_BASE,%ecx
|
||||
#ifndef CONFIG_SMP
|
||||
leaq INIT_PER_CPU_VAR(fixed_percpu_data)(%rip), %rdx
|
||||
#endif
|
||||
movl %edx, %eax
|
||||
shrq $32, %rdx
|
||||
wrmsr
|
||||
|
||||
@@ -144,7 +144,7 @@ long ksys_ioperm(unsigned long from, unsigned long num, int turn_on)
|
||||
* Update the sequence number to force a TSS update on return to
|
||||
* user mode.
|
||||
*/
|
||||
iobm->sequence = atomic64_add_return(1, &io_bitmap_sequence);
|
||||
iobm->sequence = atomic64_inc_return(&io_bitmap_sequence);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -29,12 +29,9 @@
|
||||
int sysctl_panic_on_stackoverflow __read_mostly;
|
||||
|
||||
/* Debugging check for stack overflow: is there less than 1KB free? */
|
||||
static int check_stack_overflow(void)
|
||||
static bool check_stack_overflow(void)
|
||||
{
|
||||
long sp;
|
||||
|
||||
__asm__ __volatile__("andl %%esp,%0" :
|
||||
"=r" (sp) : "0" (THREAD_SIZE - 1));
|
||||
unsigned long sp = current_stack_pointer & (THREAD_SIZE - 1);
|
||||
|
||||
return sp < (sizeof(struct thread_info) + STACK_WARN);
|
||||
}
|
||||
@@ -48,18 +45,17 @@ static void print_stack_overflow(void)
|
||||
}
|
||||
|
||||
#else
|
||||
static inline int check_stack_overflow(void) { return 0; }
|
||||
static inline bool check_stack_overflow(void) { return false; }
|
||||
static inline void print_stack_overflow(void) { }
|
||||
#endif
|
||||
|
||||
static void call_on_stack(void *func, void *stack)
|
||||
{
|
||||
asm volatile("xchgl %%ebx,%%esp \n"
|
||||
asm volatile("xchgl %[sp], %%esp\n"
|
||||
CALL_NOSPEC
|
||||
"movl %%ebx,%%esp \n"
|
||||
: "=b" (stack)
|
||||
: "0" (stack),
|
||||
[thunk_target] "D"(func)
|
||||
"movl %[sp], %%esp"
|
||||
: [sp] "+b" (stack)
|
||||
: [thunk_target] "D" (func)
|
||||
: "memory", "cc", "edx", "ecx", "eax");
|
||||
}
|
||||
|
||||
@@ -68,10 +64,10 @@ static inline void *current_stack(void)
|
||||
return (void *)(current_stack_pointer & ~(THREAD_SIZE - 1));
|
||||
}
|
||||
|
||||
static inline int execute_on_irq_stack(int overflow, struct irq_desc *desc)
|
||||
static inline bool execute_on_irq_stack(bool overflow, struct irq_desc *desc)
|
||||
{
|
||||
struct irq_stack *curstk, *irqstk;
|
||||
u32 *isp, *prev_esp, arg1;
|
||||
u32 *isp, *prev_esp;
|
||||
|
||||
curstk = (struct irq_stack *) current_stack();
|
||||
irqstk = __this_cpu_read(pcpu_hot.hardirq_stack_ptr);
|
||||
@@ -83,7 +79,7 @@ static inline int execute_on_irq_stack(int overflow, struct irq_desc *desc)
|
||||
* current stack (which is the irq stack already after all)
|
||||
*/
|
||||
if (unlikely(curstk == irqstk))
|
||||
return 0;
|
||||
return false;
|
||||
|
||||
isp = (u32 *) ((char *)irqstk + sizeof(*irqstk));
|
||||
|
||||
@@ -94,14 +90,13 @@ static inline int execute_on_irq_stack(int overflow, struct irq_desc *desc)
|
||||
if (unlikely(overflow))
|
||||
call_on_stack(print_stack_overflow, isp);
|
||||
|
||||
asm volatile("xchgl %%ebx,%%esp \n"
|
||||
asm volatile("xchgl %[sp], %%esp\n"
|
||||
CALL_NOSPEC
|
||||
"movl %%ebx,%%esp \n"
|
||||
: "=a" (arg1), "=b" (isp)
|
||||
: "0" (desc), "1" (isp),
|
||||
[thunk_target] "D" (desc->handle_irq)
|
||||
: "memory", "cc", "ecx");
|
||||
return 1;
|
||||
"movl %[sp], %%esp"
|
||||
: "+a" (desc), [sp] "+b" (isp)
|
||||
: [thunk_target] "D" (desc->handle_irq)
|
||||
: "memory", "cc", "edx", "ecx");
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -150,7 +145,7 @@ void do_softirq_own_stack(void)
|
||||
|
||||
void __handle_irq(struct irq_desc *desc, struct pt_regs *regs)
|
||||
{
|
||||
int overflow = check_stack_overflow();
|
||||
bool overflow = check_stack_overflow();
|
||||
|
||||
if (user_mode(regs) || !execute_on_irq_stack(overflow, desc)) {
|
||||
if (unlikely(overflow))
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <asm/apic.h>
|
||||
|
||||
DEFINE_PER_CPU_PAGE_ALIGNED(struct irq_stack, irq_stack_backing_store) __visible;
|
||||
DECLARE_INIT_PER_CPU(irq_stack_backing_store);
|
||||
|
||||
#ifdef CONFIG_VMAP_STACK
|
||||
/*
|
||||
|
||||
@@ -838,7 +838,6 @@ static void __init kvm_guest_init(void)
|
||||
#ifdef CONFIG_SMP
|
||||
if (pv_tlb_flush_supported()) {
|
||||
pv_ops.mmu.flush_tlb_multi = kvm_flush_tlb_multi;
|
||||
pv_ops.mmu.tlb_remove_table = tlb_remove_table;
|
||||
pr_info("KVM setup pv remote TLB flush\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <linux/jump_label.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/memory.h>
|
||||
#include <linux/stackprotector.h>
|
||||
|
||||
#include <asm/text-patching.h>
|
||||
#include <asm/page.h>
|
||||
@@ -130,6 +131,20 @@ static int __write_relocate_add(Elf64_Shdr *sechdrs,
|
||||
goto overflow;
|
||||
size = 4;
|
||||
break;
|
||||
#if defined(CONFIG_STACKPROTECTOR) && \
|
||||
defined(CONFIG_CC_IS_CLANG) && CONFIG_CLANG_VERSION < 170000
|
||||
case R_X86_64_REX_GOTPCRELX: {
|
||||
static unsigned long __percpu *const addr = &__stack_chk_guard;
|
||||
|
||||
if (sym->st_value != (u64)addr) {
|
||||
pr_err("%s: Unsupported GOTPCREL relocation\n", me->name);
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
val = (u64)&addr + rel[i].r_addend;
|
||||
fallthrough;
|
||||
}
|
||||
#endif
|
||||
case R_X86_64_PC32:
|
||||
case R_X86_64_PLT32:
|
||||
val -= (u64)loc;
|
||||
|
||||
@@ -59,21 +59,6 @@ void __init native_pv_lock_init(void)
|
||||
static_branch_enable(&virt_spin_lock_key);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_PT_RECLAIM
|
||||
static void native_tlb_remove_table(struct mmu_gather *tlb, void *table)
|
||||
{
|
||||
struct ptdesc *ptdesc = (struct ptdesc *)table;
|
||||
|
||||
pagetable_dtor(ptdesc);
|
||||
tlb_remove_page(tlb, ptdesc_page(ptdesc));
|
||||
}
|
||||
#else
|
||||
static void native_tlb_remove_table(struct mmu_gather *tlb, void *table)
|
||||
{
|
||||
tlb_remove_table(tlb, table);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct static_key paravirt_steal_enabled;
|
||||
struct static_key paravirt_steal_rq_enabled;
|
||||
|
||||
@@ -185,7 +170,6 @@ struct paravirt_patch_template pv_ops = {
|
||||
.mmu.flush_tlb_kernel = native_flush_tlb_global,
|
||||
.mmu.flush_tlb_one_user = native_flush_tlb_one_user,
|
||||
.mmu.flush_tlb_multi = native_flush_tlb_multi,
|
||||
.mmu.tlb_remove_table = native_tlb_remove_table,
|
||||
|
||||
.mmu.exit_mmap = paravirt_nop,
|
||||
.mmu.notify_page_enc_status_changed = paravirt_nop,
|
||||
|
||||
@@ -23,18 +23,10 @@
|
||||
#include <asm/cpumask.h>
|
||||
#include <asm/cpu.h>
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
#define BOOT_PERCPU_OFFSET ((unsigned long)__per_cpu_load)
|
||||
#else
|
||||
#define BOOT_PERCPU_OFFSET 0
|
||||
#endif
|
||||
|
||||
DEFINE_PER_CPU_READ_MOSTLY(unsigned long, this_cpu_off) = BOOT_PERCPU_OFFSET;
|
||||
DEFINE_PER_CPU_READ_MOSTLY(unsigned long, this_cpu_off);
|
||||
EXPORT_PER_CPU_SYMBOL(this_cpu_off);
|
||||
|
||||
unsigned long __per_cpu_offset[NR_CPUS] __ro_after_init = {
|
||||
[0 ... NR_CPUS-1] = BOOT_PERCPU_OFFSET,
|
||||
};
|
||||
unsigned long __per_cpu_offset[NR_CPUS] __ro_after_init;
|
||||
EXPORT_SYMBOL(__per_cpu_offset);
|
||||
|
||||
/*
|
||||
|
||||
@@ -33,25 +33,55 @@
|
||||
#include <asm/smap.h>
|
||||
#include <asm/gsseg.h>
|
||||
|
||||
/*
|
||||
* The first GDT descriptor is reserved as 'NULL descriptor'. As bits 0
|
||||
* and 1 of a segment selector, i.e., the RPL bits, are NOT used to index
|
||||
* GDT, selector values 0~3 all point to the NULL descriptor, thus values
|
||||
* 0, 1, 2 and 3 are all valid NULL selector values.
|
||||
*
|
||||
* However IRET zeros ES, FS, GS, and DS segment registers if any of them
|
||||
* is found to have any nonzero NULL selector value, which can be used by
|
||||
* userspace in pre-FRED systems to spot any interrupt/exception by loading
|
||||
* a nonzero NULL selector and waiting for it to become zero. Before FRED
|
||||
* there was nothing software could do to prevent such an information leak.
|
||||
*
|
||||
* ERETU, the only legit instruction to return to userspace from kernel
|
||||
* under FRED, by design does NOT zero any segment register to avoid this
|
||||
* problem behavior.
|
||||
*
|
||||
* As such, leave NULL selector values 0~3 unchanged.
|
||||
*/
|
||||
static inline u16 fixup_rpl(u16 sel)
|
||||
{
|
||||
return sel <= 3 ? sel : sel | 3;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IA32_EMULATION
|
||||
#include <asm/unistd_32_ia32.h>
|
||||
|
||||
static inline void reload_segments(struct sigcontext_32 *sc)
|
||||
{
|
||||
unsigned int cur;
|
||||
u16 cur;
|
||||
|
||||
/*
|
||||
* Reload fs and gs if they have changed in the signal
|
||||
* handler. This does not handle long fs/gs base changes in
|
||||
* the handler, but does not clobber them at least in the
|
||||
* normal case.
|
||||
*/
|
||||
savesegment(gs, cur);
|
||||
if ((sc->gs | 0x03) != cur)
|
||||
load_gs_index(sc->gs | 0x03);
|
||||
if (fixup_rpl(sc->gs) != cur)
|
||||
load_gs_index(fixup_rpl(sc->gs));
|
||||
savesegment(fs, cur);
|
||||
if ((sc->fs | 0x03) != cur)
|
||||
loadsegment(fs, sc->fs | 0x03);
|
||||
if (fixup_rpl(sc->fs) != cur)
|
||||
loadsegment(fs, fixup_rpl(sc->fs));
|
||||
|
||||
savesegment(ds, cur);
|
||||
if ((sc->ds | 0x03) != cur)
|
||||
loadsegment(ds, sc->ds | 0x03);
|
||||
if (fixup_rpl(sc->ds) != cur)
|
||||
loadsegment(ds, fixup_rpl(sc->ds));
|
||||
savesegment(es, cur);
|
||||
if ((sc->es | 0x03) != cur)
|
||||
loadsegment(es, sc->es | 0x03);
|
||||
if (fixup_rpl(sc->es) != cur)
|
||||
loadsegment(es, fixup_rpl(sc->es));
|
||||
}
|
||||
|
||||
#define sigset32_t compat_sigset_t
|
||||
@@ -105,18 +135,12 @@ static bool ia32_restore_sigcontext(struct pt_regs *regs,
|
||||
regs->orig_ax = -1;
|
||||
|
||||
#ifdef CONFIG_IA32_EMULATION
|
||||
/*
|
||||
* Reload fs and gs if they have changed in the signal
|
||||
* handler. This does not handle long fs/gs base changes in
|
||||
* the handler, but does not clobber them at least in the
|
||||
* normal case.
|
||||
*/
|
||||
reload_segments(&sc);
|
||||
#else
|
||||
loadsegment(gs, sc.gs);
|
||||
regs->fs = sc.fs;
|
||||
regs->es = sc.es;
|
||||
regs->ds = sc.ds;
|
||||
loadsegment(gs, fixup_rpl(sc.gs));
|
||||
regs->fs = fixup_rpl(sc.fs);
|
||||
regs->es = fixup_rpl(sc.es);
|
||||
regs->ds = fixup_rpl(sc.ds);
|
||||
#endif
|
||||
|
||||
return fpu__restore_sig(compat_ptr(sc.fpstate), 1);
|
||||
|
||||
@@ -190,7 +190,7 @@ static void ap_starting(void)
|
||||
apic_ap_setup();
|
||||
|
||||
/* Save the processor parameters. */
|
||||
smp_store_cpu_info(cpuid);
|
||||
identify_secondary_cpu(cpuid);
|
||||
|
||||
/*
|
||||
* The topology information must be up to date before
|
||||
@@ -215,7 +215,7 @@ static void ap_calibrate_delay(void)
|
||||
{
|
||||
/*
|
||||
* Calibrate the delay loop and update loops_per_jiffy in cpu_data.
|
||||
* smp_store_cpu_info() stored a value that is close but not as
|
||||
* identify_secondary_cpu() stored a value that is close but not as
|
||||
* accurate as the value just calculated.
|
||||
*
|
||||
* As this is invoked after the TSC synchronization check,
|
||||
@@ -316,26 +316,6 @@ static void notrace __noendbr start_secondary(void *unused)
|
||||
}
|
||||
ANNOTATE_NOENDBR_SYM(start_secondary);
|
||||
|
||||
/*
|
||||
* The bootstrap kernel entry code has set these up. Save them for
|
||||
* a given CPU
|
||||
*/
|
||||
void smp_store_cpu_info(int id)
|
||||
{
|
||||
struct cpuinfo_x86 *c = &cpu_data(id);
|
||||
|
||||
/* Copy boot_cpu_data only on the first bringup */
|
||||
if (!c->initialized)
|
||||
*c = boot_cpu_data;
|
||||
c->cpu_index = id;
|
||||
/*
|
||||
* During boot time, CPU0 has this setup already. Save the info when
|
||||
* bringing up an AP.
|
||||
*/
|
||||
identify_secondary_cpu(c);
|
||||
c->initialized = true;
|
||||
}
|
||||
|
||||
static bool
|
||||
topology_same_node(struct cpuinfo_x86 *c, struct cpuinfo_x86 *o)
|
||||
{
|
||||
@@ -1263,43 +1243,9 @@ void play_dead_common(void)
|
||||
* We need to flush the caches before going to sleep, lest we have
|
||||
* dirty data in our caches when we come back up.
|
||||
*/
|
||||
static inline void mwait_play_dead(void)
|
||||
void __noreturn mwait_play_dead(unsigned int eax_hint)
|
||||
{
|
||||
struct mwait_cpu_dead *md = this_cpu_ptr(&mwait_cpu_dead);
|
||||
unsigned int eax, ebx, ecx, edx;
|
||||
unsigned int highest_cstate = 0;
|
||||
unsigned int highest_subcstate = 0;
|
||||
int i;
|
||||
|
||||
if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD ||
|
||||
boot_cpu_data.x86_vendor == X86_VENDOR_HYGON)
|
||||
return;
|
||||
if (!this_cpu_has(X86_FEATURE_MWAIT))
|
||||
return;
|
||||
if (!this_cpu_has(X86_FEATURE_CLFLUSH))
|
||||
return;
|
||||
|
||||
eax = CPUID_LEAF_MWAIT;
|
||||
ecx = 0;
|
||||
native_cpuid(&eax, &ebx, &ecx, &edx);
|
||||
|
||||
/*
|
||||
* eax will be 0 if EDX enumeration is not valid.
|
||||
* Initialized below to cstate, sub_cstate value when EDX is valid.
|
||||
*/
|
||||
if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED)) {
|
||||
eax = 0;
|
||||
} else {
|
||||
edx >>= MWAIT_SUBSTATE_SIZE;
|
||||
for (i = 0; i < 7 && edx; i++, edx >>= MWAIT_SUBSTATE_SIZE) {
|
||||
if (edx & MWAIT_SUBSTATE_MASK) {
|
||||
highest_cstate = i;
|
||||
highest_subcstate = edx & MWAIT_SUBSTATE_MASK;
|
||||
}
|
||||
}
|
||||
eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) |
|
||||
(highest_subcstate - 1);
|
||||
}
|
||||
|
||||
/* Set up state for the kexec() hack below */
|
||||
md->status = CPUDEAD_MWAIT_WAIT;
|
||||
@@ -1320,7 +1266,7 @@ static inline void mwait_play_dead(void)
|
||||
mb();
|
||||
__monitor(md, 0, 0);
|
||||
mb();
|
||||
__mwait(eax, 0);
|
||||
__mwait(eax_hint, 0);
|
||||
|
||||
if (READ_ONCE(md->control) == CPUDEAD_MWAIT_KEXEC_HLT) {
|
||||
/*
|
||||
@@ -1392,9 +1338,9 @@ void native_play_dead(void)
|
||||
play_dead_common();
|
||||
tboot_shutdown(TB_SHUTDOWN_WFS);
|
||||
|
||||
mwait_play_dead();
|
||||
if (cpuidle_play_dead())
|
||||
hlt_play_dead();
|
||||
/* Below returns only on error. */
|
||||
cpuidle_play_dead();
|
||||
hlt_play_dead();
|
||||
}
|
||||
|
||||
#else /* ... !CONFIG_HOTPLUG_CPU */
|
||||
|
||||
@@ -152,7 +152,7 @@ static const struct x86_cpu_id tsc_msr_cpu_ids[] = {
|
||||
X86_MATCH_VFM(INTEL_ATOM_SILVERMONT, &freq_desc_byt),
|
||||
X86_MATCH_VFM(INTEL_ATOM_SILVERMONT_MID, &freq_desc_tng),
|
||||
X86_MATCH_VFM(INTEL_ATOM_AIRMONT, &freq_desc_cht),
|
||||
X86_MATCH_VFM(INTEL_ATOM_AIRMONT_MID, &freq_desc_ann),
|
||||
X86_MATCH_VFM(INTEL_ATOM_SILVERMONT_MID2, &freq_desc_ann),
|
||||
X86_MATCH_VFM(INTEL_ATOM_AIRMONT_NP, &freq_desc_lgm),
|
||||
{}
|
||||
};
|
||||
|
||||
@@ -112,12 +112,6 @@ ASSERT(__relocate_kernel_end - __relocate_kernel_start <= KEXEC_CONTROL_CODE_MAX
|
||||
PHDRS {
|
||||
text PT_LOAD FLAGS(5); /* R_E */
|
||||
data PT_LOAD FLAGS(6); /* RW_ */
|
||||
#ifdef CONFIG_X86_64
|
||||
#ifdef CONFIG_SMP
|
||||
percpu PT_LOAD FLAGS(6); /* RW_ */
|
||||
#endif
|
||||
init PT_LOAD FLAGS(7); /* RWE */
|
||||
#endif
|
||||
note PT_NOTE FLAGS(0); /* ___ */
|
||||
}
|
||||
|
||||
@@ -216,21 +210,7 @@ SECTIONS
|
||||
__init_begin = .; /* paired with __init_end */
|
||||
}
|
||||
|
||||
#if defined(CONFIG_X86_64) && defined(CONFIG_SMP)
|
||||
/*
|
||||
* percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the
|
||||
* output PHDR, so the next output section - .init.text - should
|
||||
* start another segment - init.
|
||||
*/
|
||||
PERCPU_VADDR(INTERNODE_CACHE_BYTES, 0, :percpu)
|
||||
ASSERT(SIZEOF(.data..percpu) < CONFIG_PHYSICAL_START,
|
||||
"per-CPU data too large - increase CONFIG_PHYSICAL_START")
|
||||
#endif
|
||||
|
||||
INIT_TEXT_SECTION(PAGE_SIZE)
|
||||
#ifdef CONFIG_X86_64
|
||||
:init
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Section for code used exclusively before alternatives are run. All
|
||||
@@ -347,9 +327,7 @@ SECTIONS
|
||||
EXIT_DATA
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_X86_64) || !defined(CONFIG_SMP)
|
||||
PERCPU_SECTION(INTERNODE_CACHE_BYTES)
|
||||
#endif
|
||||
|
||||
RUNTIME_CONST_VARIABLES
|
||||
RUNTIME_CONST(ptr, USER_PTR_MAX)
|
||||
@@ -493,19 +471,6 @@ SECTIONS
|
||||
PROVIDE(__ref_stack_chk_guard = __stack_chk_guard);
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
/*
|
||||
* Per-cpu symbols which need to be offset from __per_cpu_load
|
||||
* for the boot processor.
|
||||
*/
|
||||
#define INIT_PER_CPU(x) init_per_cpu__##x = ABSOLUTE(x) + __per_cpu_load
|
||||
INIT_PER_CPU(gdt_page);
|
||||
INIT_PER_CPU(fixed_percpu_data);
|
||||
INIT_PER_CPU(irq_stack_backing_store);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
. = ASSERT((fixed_percpu_data == 0),
|
||||
"fixed_percpu_data is not at start of per-cpu area");
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MITIGATION_UNRET_ENTRY
|
||||
. = ASSERT((retbleed_return_thunk & 0x3f) == 0, "retbleed_return_thunk not cacheline-aligned");
|
||||
|
||||
@@ -118,7 +118,7 @@ do_exception:
|
||||
|
||||
#else /* !CONFIG_CC_HAS_ASM_GOTO_OUTPUT */
|
||||
|
||||
asm volatile("1: vmread %2, %1\n\t"
|
||||
asm volatile("1: vmread %[field], %[output]\n\t"
|
||||
".byte 0x3e\n\t" /* branch taken hint */
|
||||
"ja 3f\n\t"
|
||||
|
||||
@@ -127,24 +127,26 @@ do_exception:
|
||||
* @field, and bounce through the trampoline to preserve
|
||||
* volatile registers.
|
||||
*/
|
||||
"xorl %k1, %k1\n\t"
|
||||
"xorl %k[output], %k[output]\n\t"
|
||||
"2:\n\t"
|
||||
"push %1\n\t"
|
||||
"push %2\n\t"
|
||||
"push %[output]\n\t"
|
||||
"push %[field]\n\t"
|
||||
"call vmread_error_trampoline\n\t"
|
||||
|
||||
/*
|
||||
* Unwind the stack. Note, the trampoline zeros out the
|
||||
* memory for @fault so that the result is '0' on error.
|
||||
*/
|
||||
"pop %2\n\t"
|
||||
"pop %1\n\t"
|
||||
"pop %[field]\n\t"
|
||||
"pop %[output]\n\t"
|
||||
"3:\n\t"
|
||||
|
||||
/* VMREAD faulted. As above, except push '1' for @fault. */
|
||||
_ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_ONE_REG, %1)
|
||||
_ASM_EXTABLE_TYPE_REG(1b, 2b, EX_TYPE_ONE_REG, %[output])
|
||||
|
||||
: ASM_CALL_CONSTRAINT, "=&r"(value) : "r"(field) : "cc");
|
||||
: ASM_CALL_CONSTRAINT, [output] "=&r" (value)
|
||||
: [field] "r" (field)
|
||||
: "cc");
|
||||
return value;
|
||||
|
||||
#endif /* CONFIG_CC_HAS_ASM_GOTO_OUTPUT */
|
||||
|
||||
@@ -56,7 +56,7 @@ ifeq ($(CONFIG_X86_32),y)
|
||||
lib-y += string_32.o
|
||||
lib-y += memmove_32.o
|
||||
lib-y += cmpxchg8b_emu.o
|
||||
ifneq ($(CONFIG_X86_CMPXCHG64),y)
|
||||
ifneq ($(CONFIG_X86_CX8),y)
|
||||
lib-y += atomic64_386_32.o
|
||||
endif
|
||||
else
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
.text
|
||||
|
||||
#ifndef CONFIG_X86_CMPXCHG64
|
||||
#ifndef CONFIG_X86_CX8
|
||||
|
||||
/*
|
||||
* Emulate 'cmpxchg8b (%esi)' on UP
|
||||
|
||||
@@ -582,7 +582,7 @@ static void __init lowmem_pfn_init(void)
|
||||
"only %luMB highmem pages available, ignoring highmem size of %luMB!\n"
|
||||
|
||||
#define MSG_HIGHMEM_TRIMMED \
|
||||
"Warning: only 4GB will be used. Use a HIGHMEM64G enabled kernel!\n"
|
||||
"Warning: only 4GB will be used. Support for for CONFIG_HIGHMEM64G was removed!\n"
|
||||
/*
|
||||
* We have more RAM than fits into lowmem - we try to put it into
|
||||
* highmem, also taking the highmem=x boot parameter into account:
|
||||
@@ -606,18 +606,13 @@ static void __init highmem_pfn_init(void)
|
||||
#ifndef CONFIG_HIGHMEM
|
||||
/* Maximum memory usable is what is directly addressable */
|
||||
printk(KERN_WARNING "Warning only %ldMB will be used.\n", MAXMEM>>20);
|
||||
if (max_pfn > MAX_NONPAE_PFN)
|
||||
printk(KERN_WARNING "Use a HIGHMEM64G enabled kernel.\n");
|
||||
else
|
||||
printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n");
|
||||
printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n");
|
||||
max_pfn = MAXMEM_PFN;
|
||||
#else /* !CONFIG_HIGHMEM */
|
||||
#ifndef CONFIG_HIGHMEM64G
|
||||
if (max_pfn > MAX_NONPAE_PFN) {
|
||||
max_pfn = MAX_NONPAE_PFN;
|
||||
printk(KERN_WARNING MSG_HIGHMEM_TRIMMED);
|
||||
}
|
||||
#endif /* !CONFIG_HIGHMEM64G */
|
||||
#endif /* !CONFIG_HIGHMEM */
|
||||
}
|
||||
|
||||
|
||||
@@ -503,6 +503,14 @@ void iounmap(volatile void __iomem *addr)
|
||||
}
|
||||
EXPORT_SYMBOL(iounmap);
|
||||
|
||||
void *arch_memremap_wb(phys_addr_t phys_addr, size_t size, unsigned long flags)
|
||||
{
|
||||
if ((flags & MEMREMAP_DEC) || cc_platform_has(CC_ATTR_HOST_MEM_ENCRYPT))
|
||||
return (void __force *)ioremap_cache(phys_addr, size);
|
||||
|
||||
return (void __force *)ioremap_encrypted(phys_addr, size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a physical pointer to a virtual kernel pointer for /dev/mem
|
||||
* access
|
||||
|
||||
@@ -113,8 +113,14 @@ void __init kernel_randomize_memory(void)
|
||||
memory_tb = DIV_ROUND_UP(max_pfn << PAGE_SHIFT, 1UL << TB_SHIFT) +
|
||||
CONFIG_RANDOMIZE_MEMORY_PHYSICAL_PADDING;
|
||||
|
||||
/* Adapt physical memory region size based on available memory */
|
||||
if (memory_tb < kaslr_regions[0].size_tb)
|
||||
/*
|
||||
* Adapt physical memory region size based on available memory,
|
||||
* except when CONFIG_PCI_P2PDMA is enabled. P2PDMA exposes the
|
||||
* device BAR space assuming the direct map space is large enough
|
||||
* for creating a ZONE_DEVICE mapping in the direct map corresponding
|
||||
* to the physical BAR address.
|
||||
*/
|
||||
if (!IS_ENABLED(CONFIG_PCI_P2PDMA) && (memory_tb < kaslr_regions[0].size_tb))
|
||||
kaslr_regions[0].size_tb = memory_tb;
|
||||
|
||||
/*
|
||||
|
||||
@@ -84,7 +84,6 @@ static unsigned long mmap_base(unsigned long rnd, unsigned long task_size,
|
||||
{
|
||||
unsigned long gap = rlim_stack->rlim_cur;
|
||||
unsigned long pad = stack_maxrandom_size(task_size) + stack_guard_gap;
|
||||
unsigned long gap_min, gap_max;
|
||||
|
||||
/* Values close to RLIM_INFINITY can overflow. */
|
||||
if (gap + pad > gap)
|
||||
@@ -94,13 +93,7 @@ static unsigned long mmap_base(unsigned long rnd, unsigned long task_size,
|
||||
* Top of mmap area (just below the process stack).
|
||||
* Leave an at least ~128 MB hole with possible stack randomization.
|
||||
*/
|
||||
gap_min = SIZE_128M;
|
||||
gap_max = (task_size / 6) * 5;
|
||||
|
||||
if (gap < gap_min)
|
||||
gap = gap_min;
|
||||
else if (gap > gap_max)
|
||||
gap = gap_max;
|
||||
gap = clamp(gap, SIZE_128M, (task_size / 6) * 5);
|
||||
|
||||
return PAGE_ALIGN(task_size - gap - rnd);
|
||||
}
|
||||
|
||||
@@ -225,14 +225,14 @@ within(unsigned long addr, unsigned long start, unsigned long end)
|
||||
return addr >= start && addr < end;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
|
||||
static inline int
|
||||
within_inclusive(unsigned long addr, unsigned long start, unsigned long end)
|
||||
{
|
||||
return addr >= start && addr <= end;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
|
||||
/*
|
||||
* The kernel image is mapped into two places in the virtual address space
|
||||
* (addresses without KASLR, of course):
|
||||
@@ -2628,7 +2628,7 @@ static int __set_pages_np(struct page *page, int numpages)
|
||||
.pgd = NULL,
|
||||
.numpages = numpages,
|
||||
.mask_set = __pgprot(0),
|
||||
.mask_clr = __pgprot(_PAGE_PRESENT | _PAGE_RW),
|
||||
.mask_clr = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY),
|
||||
.flags = CPA_NO_CHECK_ALIAS };
|
||||
|
||||
/*
|
||||
@@ -2715,7 +2715,7 @@ int __init kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address,
|
||||
.pgd = pgd,
|
||||
.numpages = numpages,
|
||||
.mask_set = __pgprot(0),
|
||||
.mask_clr = __pgprot(~page_flags & (_PAGE_NX|_PAGE_RW)),
|
||||
.mask_clr = __pgprot(~page_flags & (_PAGE_NX|_PAGE_RW|_PAGE_DIRTY)),
|
||||
.flags = CPA_NO_CHECK_ALIAS,
|
||||
};
|
||||
|
||||
@@ -2758,7 +2758,7 @@ int __init kernel_unmap_pages_in_pgd(pgd_t *pgd, unsigned long address,
|
||||
.pgd = pgd,
|
||||
.numpages = numpages,
|
||||
.mask_set = __pgprot(0),
|
||||
.mask_clr = __pgprot(_PAGE_PRESENT | _PAGE_RW),
|
||||
.mask_clr = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY),
|
||||
.flags = CPA_NO_CHECK_ALIAS,
|
||||
};
|
||||
|
||||
|
||||
@@ -12,59 +12,15 @@ phys_addr_t physical_mask __ro_after_init = (1ULL << __PHYSICAL_MASK_SHIFT) - 1;
|
||||
EXPORT_SYMBOL(physical_mask);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_HIGHPTE
|
||||
#define PGTABLE_HIGHMEM __GFP_HIGHMEM
|
||||
#else
|
||||
#define PGTABLE_HIGHMEM 0
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PARAVIRT
|
||||
#ifndef CONFIG_PT_RECLAIM
|
||||
static inline
|
||||
void paravirt_tlb_remove_table(struct mmu_gather *tlb, void *table)
|
||||
{
|
||||
struct ptdesc *ptdesc = (struct ptdesc *)table;
|
||||
|
||||
pagetable_dtor(ptdesc);
|
||||
tlb_remove_page(tlb, ptdesc_page(ptdesc));
|
||||
}
|
||||
#else
|
||||
static inline
|
||||
void paravirt_tlb_remove_table(struct mmu_gather *tlb, void *table)
|
||||
{
|
||||
tlb_remove_table(tlb, table);
|
||||
}
|
||||
#endif /* !CONFIG_PT_RECLAIM */
|
||||
#endif /* !CONFIG_PARAVIRT */
|
||||
|
||||
gfp_t __userpte_alloc_gfp = GFP_PGTABLE_USER | PGTABLE_HIGHMEM;
|
||||
|
||||
pgtable_t pte_alloc_one(struct mm_struct *mm)
|
||||
{
|
||||
return __pte_alloc_one(mm, __userpte_alloc_gfp);
|
||||
return __pte_alloc_one(mm, GFP_PGTABLE_USER);
|
||||
}
|
||||
|
||||
static int __init setup_userpte(char *arg)
|
||||
{
|
||||
if (!arg)
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* "userpte=nohigh" disables allocation of user pagetables in
|
||||
* high memory.
|
||||
*/
|
||||
if (strcmp(arg, "nohigh") == 0)
|
||||
__userpte_alloc_gfp &= ~__GFP_HIGHMEM;
|
||||
else
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
early_param("userpte", setup_userpte);
|
||||
|
||||
void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte)
|
||||
{
|
||||
paravirt_release_pte(page_to_pfn(pte));
|
||||
paravirt_tlb_remove_table(tlb, page_ptdesc(pte));
|
||||
tlb_remove_table(tlb, page_ptdesc(pte));
|
||||
}
|
||||
|
||||
#if CONFIG_PGTABLE_LEVELS > 2
|
||||
@@ -78,21 +34,21 @@ void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
|
||||
#ifdef CONFIG_X86_PAE
|
||||
tlb->need_flush_all = 1;
|
||||
#endif
|
||||
paravirt_tlb_remove_table(tlb, virt_to_ptdesc(pmd));
|
||||
tlb_remove_table(tlb, virt_to_ptdesc(pmd));
|
||||
}
|
||||
|
||||
#if CONFIG_PGTABLE_LEVELS > 3
|
||||
void ___pud_free_tlb(struct mmu_gather *tlb, pud_t *pud)
|
||||
{
|
||||
paravirt_release_pud(__pa(pud) >> PAGE_SHIFT);
|
||||
paravirt_tlb_remove_table(tlb, virt_to_ptdesc(pud));
|
||||
tlb_remove_table(tlb, virt_to_ptdesc(pud));
|
||||
}
|
||||
|
||||
#if CONFIG_PGTABLE_LEVELS > 4
|
||||
void ___p4d_free_tlb(struct mmu_gather *tlb, p4d_t *p4d)
|
||||
{
|
||||
paravirt_release_p4d(__pa(p4d) >> PAGE_SHIFT);
|
||||
paravirt_tlb_remove_table(tlb, virt_to_ptdesc(p4d));
|
||||
tlb_remove_table(tlb, virt_to_ptdesc(p4d));
|
||||
}
|
||||
#endif /* CONFIG_PGTABLE_LEVELS > 4 */
|
||||
#endif /* CONFIG_PGTABLE_LEVELS > 3 */
|
||||
|
||||
@@ -12,8 +12,6 @@ obj-$(CONFIG_X86_INTEL_CE) += ce4100.o
|
||||
obj-$(CONFIG_ACPI) += acpi.o
|
||||
obj-y += legacy.o irq.o
|
||||
|
||||
obj-$(CONFIG_STA2X11) += sta2x11-fixup.o
|
||||
|
||||
obj-$(CONFIG_X86_NUMACHIP) += numachip.o
|
||||
|
||||
obj-$(CONFIG_X86_INTEL_MID) += intel_mid_pci.o
|
||||
|
||||
@@ -1,233 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* DMA translation between STA2x11 AMBA memory mapping and the x86 memory mapping
|
||||
*
|
||||
* ST Microelectronics ConneXt (STA2X11/STA2X10)
|
||||
*
|
||||
* Copyright (c) 2010-2011 Wind River Systems, Inc.
|
||||
*/
|
||||
|
||||
#include <linux/pci.h>
|
||||
#include <linux/pci_ids.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/dma-map-ops.h>
|
||||
#include <linux/swiotlb.h>
|
||||
#include <asm/iommu.h>
|
||||
#include <asm/sta2x11.h>
|
||||
|
||||
#define STA2X11_SWIOTLB_SIZE (4*1024*1024)
|
||||
|
||||
/*
|
||||
* We build a list of bus numbers that are under the ConneXt. The
|
||||
* main bridge hosts 4 busses, which are the 4 endpoints, in order.
|
||||
*/
|
||||
#define STA2X11_NR_EP 4 /* 0..3 included */
|
||||
#define STA2X11_NR_FUNCS 8 /* 0..7 included */
|
||||
#define STA2X11_AMBA_SIZE (512 << 20)
|
||||
|
||||
struct sta2x11_ahb_regs { /* saved during suspend */
|
||||
u32 base, pexlbase, pexhbase, crw;
|
||||
};
|
||||
|
||||
struct sta2x11_mapping {
|
||||
int is_suspended;
|
||||
struct sta2x11_ahb_regs regs[STA2X11_NR_FUNCS];
|
||||
};
|
||||
|
||||
struct sta2x11_instance {
|
||||
struct list_head list;
|
||||
int bus0;
|
||||
struct sta2x11_mapping map[STA2X11_NR_EP];
|
||||
};
|
||||
|
||||
static LIST_HEAD(sta2x11_instance_list);
|
||||
|
||||
/* At probe time, record new instances of this bridge (likely one only) */
|
||||
static void sta2x11_new_instance(struct pci_dev *pdev)
|
||||
{
|
||||
struct sta2x11_instance *instance;
|
||||
|
||||
instance = kzalloc(sizeof(*instance), GFP_ATOMIC);
|
||||
if (!instance)
|
||||
return;
|
||||
/* This has a subordinate bridge, with 4 more-subordinate ones */
|
||||
instance->bus0 = pdev->subordinate->number + 1;
|
||||
|
||||
if (list_empty(&sta2x11_instance_list)) {
|
||||
int size = STA2X11_SWIOTLB_SIZE;
|
||||
/* First instance: register your own swiotlb area */
|
||||
dev_info(&pdev->dev, "Using SWIOTLB (size %i)\n", size);
|
||||
if (swiotlb_init_late(size, GFP_DMA, NULL))
|
||||
dev_emerg(&pdev->dev, "init swiotlb failed\n");
|
||||
}
|
||||
list_add(&instance->list, &sta2x11_instance_list);
|
||||
}
|
||||
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_STMICRO, 0xcc17, sta2x11_new_instance);
|
||||
|
||||
/*
|
||||
* Utility functions used in this file from below
|
||||
*/
|
||||
static struct sta2x11_instance *sta2x11_pdev_to_instance(struct pci_dev *pdev)
|
||||
{
|
||||
struct sta2x11_instance *instance;
|
||||
int ep;
|
||||
|
||||
list_for_each_entry(instance, &sta2x11_instance_list, list) {
|
||||
ep = pdev->bus->number - instance->bus0;
|
||||
if (ep >= 0 && ep < STA2X11_NR_EP)
|
||||
return instance;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int sta2x11_pdev_to_ep(struct pci_dev *pdev)
|
||||
{
|
||||
struct sta2x11_instance *instance;
|
||||
|
||||
instance = sta2x11_pdev_to_instance(pdev);
|
||||
if (!instance)
|
||||
return -1;
|
||||
|
||||
return pdev->bus->number - instance->bus0;
|
||||
}
|
||||
|
||||
/* This is exported, as some devices need to access the MFD registers */
|
||||
struct sta2x11_instance *sta2x11_get_instance(struct pci_dev *pdev)
|
||||
{
|
||||
return sta2x11_pdev_to_instance(pdev);
|
||||
}
|
||||
EXPORT_SYMBOL(sta2x11_get_instance);
|
||||
|
||||
/* At setup time, we use our own ops if the device is a ConneXt one */
|
||||
static void sta2x11_setup_pdev(struct pci_dev *pdev)
|
||||
{
|
||||
struct sta2x11_instance *instance = sta2x11_pdev_to_instance(pdev);
|
||||
|
||||
if (!instance) /* either a sta2x11 bridge or another ST device */
|
||||
return;
|
||||
|
||||
/* We must enable all devices as master, for audio DMA to work */
|
||||
pci_set_master(pdev);
|
||||
}
|
||||
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_STMICRO, PCI_ANY_ID, sta2x11_setup_pdev);
|
||||
|
||||
/*
|
||||
* At boot we must set up the mappings for the pcie-to-amba bridge.
|
||||
* It involves device access, and the same happens at suspend/resume time
|
||||
*/
|
||||
|
||||
#define AHB_MAPB 0xCA4
|
||||
#define AHB_CRW(i) (AHB_MAPB + 0 + (i) * 0x10)
|
||||
#define AHB_CRW_SZMASK 0xfffffc00UL
|
||||
#define AHB_CRW_ENABLE (1 << 0)
|
||||
#define AHB_CRW_WTYPE_MEM (2 << 1)
|
||||
#define AHB_CRW_ROE (1UL << 3) /* Relax Order Ena */
|
||||
#define AHB_CRW_NSE (1UL << 4) /* No Snoop Enable */
|
||||
#define AHB_BASE(i) (AHB_MAPB + 4 + (i) * 0x10)
|
||||
#define AHB_PEXLBASE(i) (AHB_MAPB + 8 + (i) * 0x10)
|
||||
#define AHB_PEXHBASE(i) (AHB_MAPB + 12 + (i) * 0x10)
|
||||
|
||||
/* At probe time, enable mapping for each endpoint, using the pdev */
|
||||
static void sta2x11_map_ep(struct pci_dev *pdev)
|
||||
{
|
||||
struct sta2x11_instance *instance = sta2x11_pdev_to_instance(pdev);
|
||||
struct device *dev = &pdev->dev;
|
||||
u32 amba_base, max_amba_addr;
|
||||
int i, ret;
|
||||
|
||||
if (!instance)
|
||||
return;
|
||||
|
||||
pci_read_config_dword(pdev, AHB_BASE(0), &amba_base);
|
||||
max_amba_addr = amba_base + STA2X11_AMBA_SIZE - 1;
|
||||
|
||||
ret = dma_direct_set_offset(dev, 0, amba_base, STA2X11_AMBA_SIZE);
|
||||
if (ret)
|
||||
dev_err(dev, "sta2x11: could not set DMA offset\n");
|
||||
|
||||
dev->bus_dma_limit = max_amba_addr;
|
||||
dma_set_mask_and_coherent(&pdev->dev, max_amba_addr);
|
||||
|
||||
/* Configure AHB mapping */
|
||||
pci_write_config_dword(pdev, AHB_PEXLBASE(0), 0);
|
||||
pci_write_config_dword(pdev, AHB_PEXHBASE(0), 0);
|
||||
pci_write_config_dword(pdev, AHB_CRW(0), STA2X11_AMBA_SIZE |
|
||||
AHB_CRW_WTYPE_MEM | AHB_CRW_ENABLE);
|
||||
|
||||
/* Disable all the other windows */
|
||||
for (i = 1; i < STA2X11_NR_FUNCS; i++)
|
||||
pci_write_config_dword(pdev, AHB_CRW(i), 0);
|
||||
|
||||
dev_info(&pdev->dev,
|
||||
"sta2x11: Map EP %i: AMBA address %#8x-%#8x\n",
|
||||
sta2x11_pdev_to_ep(pdev), amba_base, max_amba_addr);
|
||||
}
|
||||
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_STMICRO, PCI_ANY_ID, sta2x11_map_ep);
|
||||
|
||||
#ifdef CONFIG_PM /* Some register values must be saved and restored */
|
||||
|
||||
static struct sta2x11_mapping *sta2x11_pdev_to_mapping(struct pci_dev *pdev)
|
||||
{
|
||||
struct sta2x11_instance *instance;
|
||||
int ep;
|
||||
|
||||
instance = sta2x11_pdev_to_instance(pdev);
|
||||
if (!instance)
|
||||
return NULL;
|
||||
ep = sta2x11_pdev_to_ep(pdev);
|
||||
return instance->map + ep;
|
||||
}
|
||||
|
||||
static void suspend_mapping(struct pci_dev *pdev)
|
||||
{
|
||||
struct sta2x11_mapping *map = sta2x11_pdev_to_mapping(pdev);
|
||||
int i;
|
||||
|
||||
if (!map)
|
||||
return;
|
||||
|
||||
if (map->is_suspended)
|
||||
return;
|
||||
map->is_suspended = 1;
|
||||
|
||||
/* Save all window configs */
|
||||
for (i = 0; i < STA2X11_NR_FUNCS; i++) {
|
||||
struct sta2x11_ahb_regs *regs = map->regs + i;
|
||||
|
||||
pci_read_config_dword(pdev, AHB_BASE(i), ®s->base);
|
||||
pci_read_config_dword(pdev, AHB_PEXLBASE(i), ®s->pexlbase);
|
||||
pci_read_config_dword(pdev, AHB_PEXHBASE(i), ®s->pexhbase);
|
||||
pci_read_config_dword(pdev, AHB_CRW(i), ®s->crw);
|
||||
}
|
||||
}
|
||||
DECLARE_PCI_FIXUP_SUSPEND(PCI_VENDOR_ID_STMICRO, PCI_ANY_ID, suspend_mapping);
|
||||
|
||||
static void resume_mapping(struct pci_dev *pdev)
|
||||
{
|
||||
struct sta2x11_mapping *map = sta2x11_pdev_to_mapping(pdev);
|
||||
int i;
|
||||
|
||||
if (!map)
|
||||
return;
|
||||
|
||||
|
||||
if (!map->is_suspended)
|
||||
goto out;
|
||||
map->is_suspended = 0;
|
||||
|
||||
/* Restore all window configs */
|
||||
for (i = 0; i < STA2X11_NR_FUNCS; i++) {
|
||||
struct sta2x11_ahb_regs *regs = map->regs + i;
|
||||
|
||||
pci_write_config_dword(pdev, AHB_BASE(i), regs->base);
|
||||
pci_write_config_dword(pdev, AHB_PEXLBASE(i), regs->pexlbase);
|
||||
pci_write_config_dword(pdev, AHB_PEXHBASE(i), regs->pexhbase);
|
||||
pci_write_config_dword(pdev, AHB_CRW(i), regs->crw);
|
||||
}
|
||||
out:
|
||||
pci_set_master(pdev); /* Like at boot, enable master on all devices */
|
||||
}
|
||||
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_STMICRO, PCI_ANY_ID, resume_mapping);
|
||||
|
||||
#endif /* CONFIG_PM */
|
||||
@@ -173,10 +173,14 @@ SYM_CODE_START(pvh_start_xen)
|
||||
1:
|
||||
UNWIND_HINT_END_OF_STACK
|
||||
|
||||
/* Set base address in stack canary descriptor. */
|
||||
mov $MSR_GS_BASE,%ecx
|
||||
leal canary(%rip), %eax
|
||||
xor %edx, %edx
|
||||
/*
|
||||
* Set up GSBASE.
|
||||
* Note that on SMP the boot CPU uses the init data section until
|
||||
* the per-CPU areas are set up.
|
||||
*/
|
||||
movl $MSR_GS_BASE,%ecx
|
||||
xorl %eax, %eax
|
||||
xorl %edx, %edx
|
||||
wrmsr
|
||||
|
||||
/* Call xen_prepare_pvh() via the kernel virtual mapping */
|
||||
@@ -238,8 +242,6 @@ SYM_DATA_START_LOCAL(gdt_start)
|
||||
SYM_DATA_END_LABEL(gdt_start, SYM_L_LOCAL, gdt_end)
|
||||
|
||||
.balign 16
|
||||
SYM_DATA_LOCAL(canary, .fill 48, 1, 0)
|
||||
|
||||
SYM_DATA_START_LOCAL(early_stack)
|
||||
.fill BOOT_STACK_SIZE, 1, 0
|
||||
SYM_DATA_END_LABEL(early_stack, SYM_L_LOCAL, early_stack_end)
|
||||
|
||||
@@ -29,9 +29,13 @@ static struct relocs relocs16;
|
||||
static struct relocs relocs32;
|
||||
|
||||
#if ELF_BITS == 64
|
||||
static struct relocs relocs32neg;
|
||||
static struct relocs relocs64;
|
||||
# define FMT PRIu64
|
||||
|
||||
#ifndef R_X86_64_REX_GOTPCRELX
|
||||
# define R_X86_64_REX_GOTPCRELX 42
|
||||
#endif
|
||||
|
||||
#else
|
||||
# define FMT PRIu32
|
||||
#endif
|
||||
@@ -86,8 +90,6 @@ static const char * const sym_regex_kernel[S_NSYMTYPES] = {
|
||||
"__initramfs_start|"
|
||||
"(jiffies|jiffies_64)|"
|
||||
#if ELF_BITS == 64
|
||||
"__per_cpu_load|"
|
||||
"init_per_cpu__.*|"
|
||||
"__end_rodata_hpage_align|"
|
||||
#endif
|
||||
"_end)$"
|
||||
@@ -227,6 +229,7 @@ static const char *rel_type(unsigned type)
|
||||
REL_TYPE(R_X86_64_PC16),
|
||||
REL_TYPE(R_X86_64_8),
|
||||
REL_TYPE(R_X86_64_PC8),
|
||||
REL_TYPE(R_X86_64_REX_GOTPCRELX),
|
||||
#else
|
||||
REL_TYPE(R_386_NONE),
|
||||
REL_TYPE(R_386_32),
|
||||
@@ -284,34 +287,6 @@ static const char *sym_name(const char *sym_strtab, Elf_Sym *sym)
|
||||
return name;
|
||||
}
|
||||
|
||||
static Elf_Sym *sym_lookup(const char *symname)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < shnum; i++) {
|
||||
struct section *sec = &secs[i];
|
||||
long nsyms;
|
||||
char *strtab;
|
||||
Elf_Sym *symtab;
|
||||
Elf_Sym *sym;
|
||||
|
||||
if (sec->shdr.sh_type != SHT_SYMTAB)
|
||||
continue;
|
||||
|
||||
nsyms = sec->shdr.sh_size/sizeof(Elf_Sym);
|
||||
symtab = sec->symtab;
|
||||
strtab = sec->link->strtab;
|
||||
|
||||
for (sym = symtab; --nsyms >= 0; sym++) {
|
||||
if (!sym->st_name)
|
||||
continue;
|
||||
if (strcmp(symname, strtab + sym->st_name) == 0)
|
||||
return sym;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN
|
||||
# define le16_to_cpu(val) (val)
|
||||
# define le32_to_cpu(val) (val)
|
||||
@@ -760,84 +735,8 @@ static void walk_relocs(int (*process)(struct section *sec, Elf_Rel *rel,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The .data..percpu section is a special case for x86_64 SMP kernels.
|
||||
* It is used to initialize the actual per_cpu areas and to provide
|
||||
* definitions for the per_cpu variables that correspond to their offsets
|
||||
* within the percpu area. Since the values of all of the symbols need
|
||||
* to be offsets from the start of the per_cpu area the virtual address
|
||||
* (sh_addr) of .data..percpu is 0 in SMP kernels.
|
||||
*
|
||||
* This means that:
|
||||
*
|
||||
* Relocations that reference symbols in the per_cpu area do not
|
||||
* need further relocation (since the value is an offset relative
|
||||
* to the start of the per_cpu area that does not change).
|
||||
*
|
||||
* Relocations that apply to the per_cpu area need to have their
|
||||
* offset adjusted by by the value of __per_cpu_load to make them
|
||||
* point to the correct place in the loaded image (because the
|
||||
* virtual address of .data..percpu is 0).
|
||||
*
|
||||
* For non SMP kernels .data..percpu is linked as part of the normal
|
||||
* kernel data and does not require special treatment.
|
||||
*
|
||||
*/
|
||||
static int per_cpu_shndx = -1;
|
||||
static Elf_Addr per_cpu_load_addr;
|
||||
|
||||
static void percpu_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < shnum; i++) {
|
||||
ElfW(Sym) *sym;
|
||||
|
||||
if (strcmp(sec_name(i), ".data..percpu"))
|
||||
continue;
|
||||
|
||||
if (secs[i].shdr.sh_addr != 0) /* non SMP kernel */
|
||||
return;
|
||||
|
||||
sym = sym_lookup("__per_cpu_load");
|
||||
if (!sym)
|
||||
die("can't find __per_cpu_load\n");
|
||||
|
||||
per_cpu_shndx = i;
|
||||
per_cpu_load_addr = sym->st_value;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#if ELF_BITS == 64
|
||||
|
||||
/*
|
||||
* Check to see if a symbol lies in the .data..percpu section.
|
||||
*
|
||||
* The linker incorrectly associates some symbols with the
|
||||
* .data..percpu section so we also need to check the symbol
|
||||
* name to make sure that we classify the symbol correctly.
|
||||
*
|
||||
* The GNU linker incorrectly associates:
|
||||
* __init_begin
|
||||
* __per_cpu_load
|
||||
*
|
||||
* The "gold" linker incorrectly associates:
|
||||
* init_per_cpu__fixed_percpu_data
|
||||
* init_per_cpu__gdt_page
|
||||
*/
|
||||
static int is_percpu_sym(ElfW(Sym) *sym, const char *symname)
|
||||
{
|
||||
int shndx = sym_index(sym);
|
||||
|
||||
return (shndx == per_cpu_shndx) &&
|
||||
strcmp(symname, "__init_begin") &&
|
||||
strcmp(symname, "__per_cpu_load") &&
|
||||
strncmp(symname, "init_per_cpu_", 13);
|
||||
}
|
||||
|
||||
|
||||
static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
|
||||
const char *symname)
|
||||
{
|
||||
@@ -848,12 +747,6 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
|
||||
if (sym->st_shndx == SHN_UNDEF)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Adjust the offset if this reloc applies to the percpu section.
|
||||
*/
|
||||
if (sec->shdr.sh_info == per_cpu_shndx)
|
||||
offset += per_cpu_load_addr;
|
||||
|
||||
switch (r_type) {
|
||||
case R_X86_64_NONE:
|
||||
/* NONE can be ignored. */
|
||||
@@ -861,33 +754,23 @@ static int do_reloc64(struct section *sec, Elf_Rel *rel, ElfW(Sym) *sym,
|
||||
|
||||
case R_X86_64_PC32:
|
||||
case R_X86_64_PLT32:
|
||||
case R_X86_64_REX_GOTPCRELX:
|
||||
/*
|
||||
* PC relative relocations don't need to be adjusted unless
|
||||
* referencing a percpu symbol.
|
||||
* PC relative relocations don't need to be adjusted.
|
||||
*
|
||||
* NB: R_X86_64_PLT32 can be treated as R_X86_64_PC32.
|
||||
*/
|
||||
if (is_percpu_sym(sym, symname))
|
||||
add_reloc(&relocs32neg, offset);
|
||||
break;
|
||||
|
||||
case R_X86_64_PC64:
|
||||
/*
|
||||
* Only used by jump labels
|
||||
*/
|
||||
if (is_percpu_sym(sym, symname))
|
||||
die("Invalid R_X86_64_PC64 relocation against per-CPU symbol %s\n", symname);
|
||||
break;
|
||||
|
||||
case R_X86_64_32:
|
||||
case R_X86_64_32S:
|
||||
case R_X86_64_64:
|
||||
/*
|
||||
* References to the percpu area don't need to be adjusted.
|
||||
*/
|
||||
if (is_percpu_sym(sym, symname))
|
||||
break;
|
||||
|
||||
if (shn_abs) {
|
||||
/*
|
||||
* Whitelisted absolute symbols do not require
|
||||
@@ -1055,7 +938,8 @@ static int cmp_relocs(const void *va, const void *vb)
|
||||
|
||||
static void sort_relocs(struct relocs *r)
|
||||
{
|
||||
qsort(r->offset, r->count, sizeof(r->offset[0]), cmp_relocs);
|
||||
if (r->count)
|
||||
qsort(r->offset, r->count, sizeof(r->offset[0]), cmp_relocs);
|
||||
}
|
||||
|
||||
static int write32(uint32_t v, FILE *f)
|
||||
@@ -1099,7 +983,6 @@ static void emit_relocs(int as_text, int use_real_mode)
|
||||
/* Order the relocations for more efficient processing */
|
||||
sort_relocs(&relocs32);
|
||||
#if ELF_BITS == 64
|
||||
sort_relocs(&relocs32neg);
|
||||
sort_relocs(&relocs64);
|
||||
#else
|
||||
sort_relocs(&relocs16);
|
||||
@@ -1131,13 +1014,6 @@ static void emit_relocs(int as_text, int use_real_mode)
|
||||
/* Now print each relocation */
|
||||
for (i = 0; i < relocs64.count; i++)
|
||||
write_reloc(relocs64.offset[i], stdout);
|
||||
|
||||
/* Print a stop */
|
||||
write_reloc(0, stdout);
|
||||
|
||||
/* Now print each inverse 32-bit relocation */
|
||||
for (i = 0; i < relocs32neg.count; i++)
|
||||
write_reloc(relocs32neg.offset[i], stdout);
|
||||
#endif
|
||||
|
||||
/* Print a stop */
|
||||
@@ -1190,9 +1066,6 @@ void process(FILE *fp, int use_real_mode, int as_text,
|
||||
read_symtabs(fp);
|
||||
read_relocs(fp);
|
||||
|
||||
if (ELF_BITS == 64)
|
||||
percpu_init();
|
||||
|
||||
if (show_absolute_syms) {
|
||||
print_absolute_symbols();
|
||||
return;
|
||||
|
||||
@@ -9,7 +9,7 @@ config XEN
|
||||
select PARAVIRT_CLOCK
|
||||
select X86_HV_CALLBACK_VECTOR
|
||||
depends on X86_64 || (X86_32 && X86_PAE)
|
||||
depends on X86_64 || (X86_GENERIC || MPENTIUM4 || MCORE2 || MATOM || MK8)
|
||||
depends on X86_64 || (X86_GENERIC || MPENTIUM4 || MATOM)
|
||||
depends on X86_LOCAL_APIC && X86_TSC
|
||||
help
|
||||
This is the Linux Xen port. Enabling this will allow the
|
||||
|
||||
@@ -2189,7 +2189,6 @@ static const typeof(pv_ops) xen_mmu_ops __initconst = {
|
||||
.flush_tlb_kernel = xen_flush_tlb,
|
||||
.flush_tlb_one_user = xen_flush_tlb_one_user,
|
||||
.flush_tlb_multi = xen_flush_tlb_multi,
|
||||
.tlb_remove_table = tlb_remove_table,
|
||||
|
||||
.pgd_alloc = xen_pgd_alloc,
|
||||
.pgd_free = xen_pgd_free,
|
||||
|
||||
@@ -70,7 +70,7 @@ static void cpu_bringup(void)
|
||||
xen_enable_syscall();
|
||||
}
|
||||
cpu = smp_processor_id();
|
||||
smp_store_cpu_info(cpu);
|
||||
identify_secondary_cpu(cpu);
|
||||
set_cpu_sibling_map(cpu);
|
||||
|
||||
speculative_store_bypass_ht_init();
|
||||
|
||||
@@ -31,16 +31,14 @@ SYM_CODE_START(startup_xen)
|
||||
|
||||
leaq __top_init_kernel_stack(%rip), %rsp
|
||||
|
||||
/* Set up %gs.
|
||||
*
|
||||
* The base of %gs always points to fixed_percpu_data. If the
|
||||
* stack protector canary is enabled, it is located at %gs:40.
|
||||
/*
|
||||
* Set up GSBASE.
|
||||
* Note that, on SMP, the boot cpu uses init data section until
|
||||
* the per cpu areas are set up.
|
||||
*/
|
||||
movl $MSR_GS_BASE,%ecx
|
||||
movq $INIT_PER_CPU_VAR(fixed_percpu_data),%rax
|
||||
cdq
|
||||
xorl %eax, %eax
|
||||
xorl %edx, %edx
|
||||
wrmsr
|
||||
|
||||
mov %rsi, %rdi
|
||||
|
||||
@@ -590,6 +590,8 @@ static void acpi_idle_play_dead(struct cpuidle_device *dev, int index)
|
||||
raw_safe_halt();
|
||||
else if (cx->entry_method == ACPI_CSTATE_SYSTEMIO) {
|
||||
io_idle(cx->address);
|
||||
} else if (cx->entry_method == ACPI_CSTATE_FFH) {
|
||||
acpi_processor_ffh_play_dead(cx);
|
||||
} else
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2200,28 +2200,20 @@ static int knl_get_turbo_pstate(int cpu)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hybrid_get_type(void *data)
|
||||
{
|
||||
u8 *cpu_type = data;
|
||||
|
||||
*cpu_type = get_this_hybrid_cpu_type();
|
||||
}
|
||||
|
||||
static int hwp_get_cpu_scaling(int cpu)
|
||||
{
|
||||
if (hybrid_scaling_factor) {
|
||||
u8 cpu_type = 0;
|
||||
|
||||
smp_call_function_single(cpu, hybrid_get_type, &cpu_type, 1);
|
||||
struct cpuinfo_x86 *c = &cpu_data(smp_processor_id());
|
||||
u8 cpu_type = c->topo.intel_type;
|
||||
|
||||
/*
|
||||
* Return the hybrid scaling factor for P-cores and use the
|
||||
* default core scaling for E-cores.
|
||||
*/
|
||||
if (cpu_type == 0x40)
|
||||
if (cpu_type == INTEL_CPU_TYPE_CORE)
|
||||
return hybrid_scaling_factor;
|
||||
|
||||
if (cpu_type == 0x20)
|
||||
if (cpu_type == INTEL_CPU_TYPE_ATOM)
|
||||
return core_get_scaling();
|
||||
}
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
#include <asm/spec-ctrl.h>
|
||||
#include <asm/tsc.h>
|
||||
#include <asm/fpu/api.h>
|
||||
#include <asm/smp.h>
|
||||
|
||||
#define INTEL_IDLE_VERSION "0.5.1"
|
||||
|
||||
@@ -229,6 +230,15 @@ static __cpuidle int intel_idle_s2idle(struct cpuidle_device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void intel_idle_enter_dead(struct cpuidle_device *dev, int index)
|
||||
{
|
||||
struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
|
||||
struct cpuidle_state *state = &drv->states[index];
|
||||
unsigned long eax = flg2MWAIT(state->flags);
|
||||
|
||||
mwait_play_dead(eax);
|
||||
}
|
||||
|
||||
/*
|
||||
* States are indexed by the cstate number,
|
||||
* which is also the index into the MWAIT hint array.
|
||||
@@ -1804,6 +1814,7 @@ static void __init intel_idle_init_cstates_acpi(struct cpuidle_driver *drv)
|
||||
mark_tsc_unstable("TSC halts in idle");
|
||||
|
||||
state->enter = intel_idle;
|
||||
state->enter_dead = intel_idle_enter_dead;
|
||||
state->enter_s2idle = intel_idle_s2idle;
|
||||
}
|
||||
}
|
||||
@@ -2153,6 +2164,9 @@ static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv)
|
||||
!cpuidle_state_table[cstate].enter_s2idle)
|
||||
break;
|
||||
|
||||
if (!cpuidle_state_table[cstate].enter_dead)
|
||||
cpuidle_state_table[cstate].enter_dead = intel_idle_enter_dead;
|
||||
|
||||
/* If marked as unusable, skip this state. */
|
||||
if (cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_UNUSABLE) {
|
||||
pr_debug("state %s is disabled\n",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
config INTEL_MEI
|
||||
tristate "Intel Management Engine Interface"
|
||||
depends on X86 && PCI
|
||||
default GENERIC_CPU || MCORE2 || MATOM || X86_GENERIC
|
||||
default X86_64 || MATOM
|
||||
help
|
||||
The Intel Management Engine (Intel ME) provides Manageability,
|
||||
Security and Media services for system containing Intel chipsets.
|
||||
|
||||
@@ -203,6 +203,12 @@ config PCI_P2PDMA
|
||||
P2P DMA transactions must be between devices behind the same root
|
||||
port.
|
||||
|
||||
Enabling this option will reduce the entropy of x86 KASLR memory
|
||||
regions. For example - on a 46 bit system, the entropy goes down
|
||||
from 16 bits to 15 bits. The actual reduction in entropy depends
|
||||
on the physical address bits, on processor features, kernel config
|
||||
(5 level page table) and physical memory present on the system.
|
||||
|
||||
If unsure, say N.
|
||||
|
||||
config PCI_LABEL
|
||||
|
||||
@@ -1274,7 +1274,7 @@ static const struct x86_cpu_id rapl_ids[] __initconst = {
|
||||
X86_MATCH_VFM(INTEL_ATOM_SILVERMONT, &rapl_defaults_byt),
|
||||
X86_MATCH_VFM(INTEL_ATOM_AIRMONT, &rapl_defaults_cht),
|
||||
X86_MATCH_VFM(INTEL_ATOM_SILVERMONT_MID, &rapl_defaults_tng),
|
||||
X86_MATCH_VFM(INTEL_ATOM_AIRMONT_MID, &rapl_defaults_ann),
|
||||
X86_MATCH_VFM(INTEL_ATOM_SILVERMONT_MID2,&rapl_defaults_ann),
|
||||
X86_MATCH_VFM(INTEL_ATOM_GOLDMONT, &rapl_defaults_core),
|
||||
X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_PLUS, &rapl_defaults_core),
|
||||
X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_D, &rapl_defaults_core),
|
||||
|
||||
@@ -172,10 +172,10 @@ void atomisp_unregister_subdev(struct v4l2_subdev *subdev);
|
||||
#define IS_BYT __IS_SOC(INTEL_ATOM_SILVERMONT)
|
||||
#define IS_CHT __IS_SOC(INTEL_ATOM_AIRMONT)
|
||||
#define IS_MRFD __IS_SOC(INTEL_ATOM_SILVERMONT_MID)
|
||||
#define IS_MOFD __IS_SOC(INTEL_ATOM_AIRMONT_MID)
|
||||
#define IS_MOFD __IS_SOC(INTEL_ATOM_SILVERMONT_MID2)
|
||||
|
||||
/* Both CHT and MOFD come with ISP2401 */
|
||||
#define IS_ISP2401 __IS_SOCS(INTEL_ATOM_AIRMONT, \
|
||||
INTEL_ATOM_AIRMONT_MID)
|
||||
INTEL_ATOM_SILVERMONT_MID2)
|
||||
|
||||
#endif /* ATOMISP_PLATFORM_H_ */
|
||||
|
||||
@@ -106,7 +106,7 @@ static const struct x86_cpu_id intel_tcc_cpu_ids[] __initconst = {
|
||||
X86_MATCH_VFM(INTEL_ATOM_SILVERMONT_D, &temp_broadwell),
|
||||
X86_MATCH_VFM(INTEL_ATOM_SILVERMONT_MID, &temp_broadwell),
|
||||
X86_MATCH_VFM(INTEL_ATOM_AIRMONT, &temp_broadwell),
|
||||
X86_MATCH_VFM(INTEL_ATOM_AIRMONT_MID, &temp_broadwell),
|
||||
X86_MATCH_VFM(INTEL_ATOM_SILVERMONT_MID2, &temp_broadwell),
|
||||
X86_MATCH_VFM(INTEL_ATOM_AIRMONT_NP, &temp_broadwell),
|
||||
X86_MATCH_VFM(INTEL_ATOM_GOLDMONT, &temp_goldmont),
|
||||
X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_D, &temp_goldmont),
|
||||
|
||||
@@ -280,6 +280,7 @@ int acpi_processor_ffh_cstate_probe(unsigned int cpu,
|
||||
struct acpi_processor_cx *cx,
|
||||
struct acpi_power_register *reg);
|
||||
void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx *cstate);
|
||||
void __noreturn acpi_processor_ffh_play_dead(struct acpi_processor_cx *cx);
|
||||
#else
|
||||
static inline void acpi_processor_power_init_bm_check(struct
|
||||
acpi_processor_flags
|
||||
@@ -300,6 +301,10 @@ static inline void acpi_processor_ffh_cstate_enter(struct acpi_processor_cx
|
||||
{
|
||||
return;
|
||||
}
|
||||
static inline void __noreturn acpi_processor_ffh_play_dead(struct acpi_processor_cx *cx)
|
||||
{
|
||||
BUG();
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int call_on_cpu(int cpu, long (*fn)(void *), void *arg,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user