mirror of
https://github.com/torvalds/linux.git
synced 2026-08-01 03:59:40 +02:00
Merge 1de564b8c1 ("Merge tag 'x86_build_for_v5.19_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip") into android-mainline
Steps on the way to 5.19-rc1 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I3cd81b95b3bcfb2f0d35701879314e6f69e9cc42
This commit is contained in:
commit
7a4e825684
|
|
@ -631,12 +631,17 @@
|
|||
Defaults to zero when built as a module and to
|
||||
10 seconds when built into the kernel.
|
||||
|
||||
clearcpuid=BITNUM[,BITNUM...] [X86]
|
||||
clearcpuid=X[,X...] [X86]
|
||||
Disable CPUID feature X for the kernel. See
|
||||
arch/x86/include/asm/cpufeatures.h for the valid bit
|
||||
numbers. Note the Linux specific bits are not necessarily
|
||||
stable over kernel options, but the vendor specific
|
||||
numbers X. Note the Linux-specific bits are not necessarily
|
||||
stable over kernel options, but the vendor-specific
|
||||
ones should be.
|
||||
X can also be a string as appearing in the flags: line
|
||||
in /proc/cpuinfo which does not have the above
|
||||
instability issue. However, not all features have names
|
||||
in /proc/cpuinfo.
|
||||
Note that using this option will taint your kernel.
|
||||
Also note that user programs calling CPUID directly
|
||||
or using the feature without checking anything
|
||||
will still see it. This just prevents it from
|
||||
|
|
@ -3486,8 +3491,6 @@
|
|||
|
||||
nocache [ARM]
|
||||
|
||||
noclflush [BUGS=X86] Don't use the CLFLUSH instruction
|
||||
|
||||
delayacct [KNL] Enable per-task delay accounting
|
||||
|
||||
nodsp [SH] Disable hardware DSP at boot time.
|
||||
|
|
@ -3498,16 +3501,11 @@
|
|||
|
||||
noexec [IA-64]
|
||||
|
||||
noexec [X86]
|
||||
On X86-32 available only on PAE configured kernels.
|
||||
noexec=on: enable non-executable mappings (default)
|
||||
noexec=off: disable non-executable mappings
|
||||
|
||||
nosmap [X86,PPC]
|
||||
nosmap [PPC]
|
||||
Disable SMAP (Supervisor Mode Access Prevention)
|
||||
even if it is supported by processor.
|
||||
|
||||
nosmep [X86,PPC64s]
|
||||
nosmep [PPC64s]
|
||||
Disable SMEP (Supervisor Mode Execution Prevention)
|
||||
even if it is supported by processor.
|
||||
|
||||
|
|
@ -3707,8 +3705,6 @@
|
|||
|
||||
nosbagart [IA-64]
|
||||
|
||||
nosep [BUGS=X86-32] Disables x86 SYSENTER/SYSEXIT support.
|
||||
|
||||
nosgx [X86-64,SGX] Disables Intel SGX kernel support.
|
||||
|
||||
nosmp [SMP] Tells an SMP kernel to act as a UP kernel,
|
||||
|
|
|
|||
|
|
@ -437,6 +437,20 @@ in a private repository which allows interested people to easily pull the
|
|||
series for testing. The usual way to offer this is a git URL in the cover
|
||||
letter of the patch series.
|
||||
|
||||
Testing
|
||||
^^^^^^^
|
||||
|
||||
Code should be tested before submitting to the tip maintainers. Anything
|
||||
other than minor changes should be built, booted and tested with
|
||||
comprehensive (and heavyweight) kernel debugging options enabled.
|
||||
|
||||
These debugging options can be found in kernel/configs/x86_debug.config
|
||||
and can be added to an existing kernel config by running:
|
||||
|
||||
make x86_debug.config
|
||||
|
||||
Some of these options are x86-specific and can be left out when testing
|
||||
on other architectures.
|
||||
|
||||
Coding style notes
|
||||
------------------
|
||||
|
|
|
|||
|
|
@ -140,9 +140,8 @@ from #define X86_FEATURE_UMIP (16*32 + 2).
|
|||
|
||||
In addition, there exists a variety of custom command-line parameters that
|
||||
disable specific features. The list of parameters includes, but is not limited
|
||||
to, nofsgsbase, nosmap, and nosmep. 5-level paging can also be disabled using
|
||||
"no5lvl". SMAP and SMEP are disabled with the aforementioned parameters,
|
||||
respectively.
|
||||
to, nofsgsbase, nosgx, noxsave, etc. 5-level paging can also be disabled using
|
||||
"no5lvl".
|
||||
|
||||
e: The feature was known to be non-functional.
|
||||
----------------------------------------------
|
||||
|
|
|
|||
|
|
@ -157,15 +157,6 @@ Rebooting
|
|||
newer BIOS, or newer board) using this option will ignore the built-in
|
||||
quirk table, and use the generic default reboot actions.
|
||||
|
||||
Non Executable Mappings
|
||||
=======================
|
||||
|
||||
noexec=on|off
|
||||
on
|
||||
Enable(default)
|
||||
off
|
||||
Disable
|
||||
|
||||
NUMA
|
||||
====
|
||||
|
||||
|
|
|
|||
|
|
@ -1831,17 +1831,6 @@ config ARCH_RANDOM
|
|||
If supported, this is a high bandwidth, cryptographically
|
||||
secure hardware random number generator.
|
||||
|
||||
config X86_SMAP
|
||||
def_bool y
|
||||
prompt "Supervisor Mode Access Prevention" if EXPERT
|
||||
help
|
||||
Supervisor Mode Access Prevention (SMAP) is a security
|
||||
feature in newer Intel processors. There is a small
|
||||
performance cost if this enabled and turned on; there is
|
||||
also a small increase in the kernel size if this is enabled.
|
||||
|
||||
If unsure, say Y.
|
||||
|
||||
config X86_UMIP
|
||||
def_bool y
|
||||
prompt "User Mode Instruction Prevention" if EXPERT
|
||||
|
|
|
|||
|
|
@ -316,5 +316,6 @@ define archhelp
|
|||
echo ''
|
||||
echo ' kvm_guest.config - Enable Kconfig items for running this kernel as a KVM guest'
|
||||
echo ' xen.config - Enable Kconfig items for running this kernel as a Xen guest'
|
||||
echo ' x86_debug.config - Enable tip tree debugging options for testing'
|
||||
|
||||
endef
|
||||
|
|
|
|||
|
|
@ -77,66 +77,78 @@ typedef unsigned int addr_t;
|
|||
|
||||
static inline u8 rdfs8(addr_t addr)
|
||||
{
|
||||
u8 *ptr = (u8 *)absolute_pointer(addr);
|
||||
u8 v;
|
||||
asm volatile("movb %%fs:%1,%0" : "=q" (v) : "m" (*(u8 *)addr));
|
||||
asm volatile("movb %%fs:%1,%0" : "=q" (v) : "m" (*ptr));
|
||||
return v;
|
||||
}
|
||||
static inline u16 rdfs16(addr_t addr)
|
||||
{
|
||||
u16 *ptr = (u16 *)absolute_pointer(addr);
|
||||
u16 v;
|
||||
asm volatile("movw %%fs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
|
||||
asm volatile("movw %%fs:%1,%0" : "=r" (v) : "m" (*ptr));
|
||||
return v;
|
||||
}
|
||||
static inline u32 rdfs32(addr_t addr)
|
||||
{
|
||||
u32 *ptr = (u32 *)absolute_pointer(addr);
|
||||
u32 v;
|
||||
asm volatile("movl %%fs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
|
||||
asm volatile("movl %%fs:%1,%0" : "=r" (v) : "m" (*ptr));
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline void wrfs8(u8 v, addr_t addr)
|
||||
{
|
||||
asm volatile("movb %1,%%fs:%0" : "+m" (*(u8 *)addr) : "qi" (v));
|
||||
u8 *ptr = (u8 *)absolute_pointer(addr);
|
||||
asm volatile("movb %1,%%fs:%0" : "+m" (*ptr) : "qi" (v));
|
||||
}
|
||||
static inline void wrfs16(u16 v, addr_t addr)
|
||||
{
|
||||
asm volatile("movw %1,%%fs:%0" : "+m" (*(u16 *)addr) : "ri" (v));
|
||||
u16 *ptr = (u16 *)absolute_pointer(addr);
|
||||
asm volatile("movw %1,%%fs:%0" : "+m" (*ptr) : "ri" (v));
|
||||
}
|
||||
static inline void wrfs32(u32 v, addr_t addr)
|
||||
{
|
||||
asm volatile("movl %1,%%fs:%0" : "+m" (*(u32 *)addr) : "ri" (v));
|
||||
u32 *ptr = (u32 *)absolute_pointer(addr);
|
||||
asm volatile("movl %1,%%fs:%0" : "+m" (*ptr) : "ri" (v));
|
||||
}
|
||||
|
||||
static inline u8 rdgs8(addr_t addr)
|
||||
{
|
||||
u8 *ptr = (u8 *)absolute_pointer(addr);
|
||||
u8 v;
|
||||
asm volatile("movb %%gs:%1,%0" : "=q" (v) : "m" (*(u8 *)addr));
|
||||
asm volatile("movb %%gs:%1,%0" : "=q" (v) : "m" (*ptr));
|
||||
return v;
|
||||
}
|
||||
static inline u16 rdgs16(addr_t addr)
|
||||
{
|
||||
u16 *ptr = (u16 *)absolute_pointer(addr);
|
||||
u16 v;
|
||||
asm volatile("movw %%gs:%1,%0" : "=r" (v) : "m" (*(u16 *)addr));
|
||||
asm volatile("movw %%gs:%1,%0" : "=r" (v) : "m" (*ptr));
|
||||
return v;
|
||||
}
|
||||
static inline u32 rdgs32(addr_t addr)
|
||||
{
|
||||
u32 *ptr = (u32 *)absolute_pointer(addr);
|
||||
u32 v;
|
||||
asm volatile("movl %%gs:%1,%0" : "=r" (v) : "m" (*(u32 *)addr));
|
||||
asm volatile("movl %%gs:%1,%0" : "=r" (v) : "m" (*ptr));
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline void wrgs8(u8 v, addr_t addr)
|
||||
{
|
||||
asm volatile("movb %1,%%gs:%0" : "+m" (*(u8 *)addr) : "qi" (v));
|
||||
u8 *ptr = (u8 *)absolute_pointer(addr);
|
||||
asm volatile("movb %1,%%gs:%0" : "+m" (*ptr) : "qi" (v));
|
||||
}
|
||||
static inline void wrgs16(u16 v, addr_t addr)
|
||||
{
|
||||
asm volatile("movw %1,%%gs:%0" : "+m" (*(u16 *)addr) : "ri" (v));
|
||||
u16 *ptr = (u16 *)absolute_pointer(addr);
|
||||
asm volatile("movw %1,%%gs:%0" : "+m" (*ptr) : "ri" (v));
|
||||
}
|
||||
static inline void wrgs32(u32 v, addr_t addr)
|
||||
{
|
||||
asm volatile("movl %1,%%gs:%0" : "+m" (*(u32 *)addr) : "ri" (v));
|
||||
u32 *ptr = (u32 *)absolute_pointer(addr);
|
||||
asm volatile("movl %1,%%gs:%0" : "+m" (*ptr) : "ri" (v));
|
||||
}
|
||||
|
||||
/* Note: these only return true/false, not a signed return value! */
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ static void copy_boot_params(void)
|
|||
u16 cl_offset;
|
||||
};
|
||||
const struct old_cmdline * const oldcmd =
|
||||
(const struct old_cmdline *)OLD_CL_ADDRESS;
|
||||
absolute_pointer(OLD_CL_ADDRESS);
|
||||
|
||||
BUILD_BUG_ON(sizeof(boot_params) != 4096);
|
||||
memcpy(&boot_params.hdr, &hdr, sizeof(hdr));
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ For 32-bit we have the following conventions - kernel is built with
|
|||
* for assembly code:
|
||||
*/
|
||||
|
||||
.macro PUSH_REGS rdx=%rdx rax=%rax save_ret=0
|
||||
.macro PUSH_REGS rdx=%rdx rcx=%rcx rax=%rax save_ret=0
|
||||
.if \save_ret
|
||||
pushq %rsi /* pt_regs->si */
|
||||
movq 8(%rsp), %rsi /* temporarily store the return address in %rsi */
|
||||
|
|
@ -73,7 +73,7 @@ For 32-bit we have the following conventions - kernel is built with
|
|||
pushq %rsi /* pt_regs->si */
|
||||
.endif
|
||||
pushq \rdx /* pt_regs->dx */
|
||||
pushq %rcx /* pt_regs->cx */
|
||||
pushq \rcx /* pt_regs->cx */
|
||||
pushq \rax /* pt_regs->ax */
|
||||
pushq %r8 /* pt_regs->r8 */
|
||||
pushq %r9 /* pt_regs->r9 */
|
||||
|
|
@ -99,6 +99,7 @@ For 32-bit we have the following conventions - kernel is built with
|
|||
* well before they could be put to use in a speculative execution
|
||||
* gadget.
|
||||
*/
|
||||
xorl %esi, %esi /* nospec si */
|
||||
xorl %edx, %edx /* nospec dx */
|
||||
xorl %ecx, %ecx /* nospec cx */
|
||||
xorl %r8d, %r8d /* nospec r8 */
|
||||
|
|
@ -114,32 +115,24 @@ For 32-bit we have the following conventions - kernel is built with
|
|||
|
||||
.endm
|
||||
|
||||
.macro PUSH_AND_CLEAR_REGS rdx=%rdx rax=%rax save_ret=0
|
||||
PUSH_REGS rdx=\rdx, rax=\rax, save_ret=\save_ret
|
||||
.macro PUSH_AND_CLEAR_REGS rdx=%rdx rcx=%rcx rax=%rax save_ret=0
|
||||
PUSH_REGS rdx=\rdx, rcx=\rcx, rax=\rax, save_ret=\save_ret
|
||||
CLEAR_REGS
|
||||
.endm
|
||||
|
||||
.macro POP_REGS pop_rdi=1 skip_r11rcx=0
|
||||
.macro POP_REGS pop_rdi=1
|
||||
popq %r15
|
||||
popq %r14
|
||||
popq %r13
|
||||
popq %r12
|
||||
popq %rbp
|
||||
popq %rbx
|
||||
.if \skip_r11rcx
|
||||
popq %rsi
|
||||
.else
|
||||
popq %r11
|
||||
.endif
|
||||
popq %r10
|
||||
popq %r9
|
||||
popq %r8
|
||||
popq %rax
|
||||
.if \skip_r11rcx
|
||||
popq %rsi
|
||||
.else
|
||||
popq %rcx
|
||||
.endif
|
||||
popq %rdx
|
||||
popq %rsi
|
||||
.if \pop_rdi
|
||||
|
|
|
|||
|
|
@ -191,8 +191,7 @@ SYM_INNER_LABEL(entry_SYSCALL_64_after_hwframe, SYM_L_GLOBAL)
|
|||
* perf profiles. Nothing jumps here.
|
||||
*/
|
||||
syscall_return_via_sysret:
|
||||
/* rcx and r11 are already restored (see code above) */
|
||||
POP_REGS pop_rdi=0 skip_r11rcx=1
|
||||
POP_REGS pop_rdi=0
|
||||
|
||||
/*
|
||||
* Now all regs are restored except RSP and RDI.
|
||||
|
|
@ -323,6 +322,14 @@ SYM_CODE_END(ret_from_fork)
|
|||
#endif
|
||||
.endm
|
||||
|
||||
/* Save all registers in pt_regs */
|
||||
SYM_CODE_START_LOCAL(push_and_clear_regs)
|
||||
UNWIND_HINT_FUNC
|
||||
PUSH_AND_CLEAR_REGS save_ret=1
|
||||
ENCODE_FRAME_POINTER 8
|
||||
RET
|
||||
SYM_CODE_END(push_and_clear_regs)
|
||||
|
||||
/**
|
||||
* idtentry_body - Macro to emit code calling the C function
|
||||
* @cfunc: C function to be called
|
||||
|
|
@ -330,7 +337,21 @@ SYM_CODE_END(ret_from_fork)
|
|||
*/
|
||||
.macro idtentry_body cfunc has_error_code:req
|
||||
|
||||
call error_entry
|
||||
call push_and_clear_regs
|
||||
UNWIND_HINT_REGS
|
||||
|
||||
/*
|
||||
* Call error_entry() and switch to the task stack if from userspace.
|
||||
*
|
||||
* When in XENPV, it is already in the task stack, and it can't fault
|
||||
* for native_iret() nor native_load_gs_index() since XENPV uses its
|
||||
* own pvops for IRET and load_gs_index(). And it doesn't need to
|
||||
* switch the CR3. So it can skip invoking error_entry().
|
||||
*/
|
||||
ALTERNATIVE "call error_entry; movq %rax, %rsp", \
|
||||
"", X86_FEATURE_XENPV
|
||||
|
||||
ENCODE_FRAME_POINTER
|
||||
UNWIND_HINT_REGS
|
||||
|
||||
movq %rsp, %rdi /* pt_regs pointer into 1st argument*/
|
||||
|
|
@ -363,6 +384,7 @@ SYM_CODE_START(\asmsym)
|
|||
UNWIND_HINT_IRET_REGS offset=\has_error_code*8
|
||||
ENDBR
|
||||
ASM_CLAC
|
||||
cld
|
||||
|
||||
.if \has_error_code == 0
|
||||
pushq $-1 /* ORIG_RAX: no syscall to restart */
|
||||
|
|
@ -431,6 +453,7 @@ SYM_CODE_START(\asmsym)
|
|||
UNWIND_HINT_IRET_REGS
|
||||
ENDBR
|
||||
ASM_CLAC
|
||||
cld
|
||||
|
||||
pushq $-1 /* ORIG_RAX: no syscall to restart */
|
||||
|
||||
|
|
@ -487,6 +510,7 @@ SYM_CODE_START(\asmsym)
|
|||
UNWIND_HINT_IRET_REGS
|
||||
ENDBR
|
||||
ASM_CLAC
|
||||
cld
|
||||
|
||||
/*
|
||||
* If the entry is from userspace, switch stacks and treat it as
|
||||
|
|
@ -550,6 +574,7 @@ SYM_CODE_START(\asmsym)
|
|||
UNWIND_HINT_IRET_REGS offset=8
|
||||
ENDBR
|
||||
ASM_CLAC
|
||||
cld
|
||||
|
||||
/* paranoid_entry returns GS information for paranoid_exit in EBX. */
|
||||
call paranoid_entry
|
||||
|
|
@ -875,7 +900,6 @@ SYM_CODE_END(xen_failsafe_callback)
|
|||
*/
|
||||
SYM_CODE_START_LOCAL(paranoid_entry)
|
||||
UNWIND_HINT_FUNC
|
||||
cld
|
||||
PUSH_AND_CLEAR_REGS save_ret=1
|
||||
ENCODE_FRAME_POINTER 8
|
||||
|
||||
|
|
@ -989,13 +1013,10 @@ SYM_CODE_START_LOCAL(paranoid_exit)
|
|||
SYM_CODE_END(paranoid_exit)
|
||||
|
||||
/*
|
||||
* Save all registers in pt_regs, and switch GS if needed.
|
||||
* Switch GS and CR3 if needed.
|
||||
*/
|
||||
SYM_CODE_START_LOCAL(error_entry)
|
||||
UNWIND_HINT_FUNC
|
||||
cld
|
||||
PUSH_AND_CLEAR_REGS save_ret=1
|
||||
ENCODE_FRAME_POINTER 8
|
||||
testb $3, CS+8(%rsp)
|
||||
jz .Lerror_kernelspace
|
||||
|
||||
|
|
@ -1003,19 +1024,15 @@ SYM_CODE_START_LOCAL(error_entry)
|
|||
* We entered from user mode or we're pretending to have entered
|
||||
* from user mode due to an IRET fault.
|
||||
*/
|
||||
SWAPGS
|
||||
swapgs
|
||||
FENCE_SWAPGS_USER_ENTRY
|
||||
/* We have user CR3. Change to kernel CR3. */
|
||||
SWITCH_TO_KERNEL_CR3 scratch_reg=%rax
|
||||
|
||||
leaq 8(%rsp), %rdi /* arg0 = pt_regs pointer */
|
||||
.Lerror_entry_from_usermode_after_swapgs:
|
||||
/* Put us onto the real thread stack. */
|
||||
popq %r12 /* save return addr in %12 */
|
||||
movq %rsp, %rdi /* arg0 = pt_regs pointer */
|
||||
call sync_regs
|
||||
movq %rax, %rsp /* switch stack */
|
||||
ENCODE_FRAME_POINTER
|
||||
pushq %r12
|
||||
RET
|
||||
|
||||
/*
|
||||
|
|
@ -1039,7 +1056,7 @@ SYM_CODE_START_LOCAL(error_entry)
|
|||
* gsbase and proceed. We'll fix up the exception and land in
|
||||
* .Lgs_change's error handler with kernel gsbase.
|
||||
*/
|
||||
SWAPGS
|
||||
swapgs
|
||||
|
||||
/*
|
||||
* Issue an LFENCE to prevent GS speculation, regardless of whether it is a
|
||||
|
|
@ -1047,6 +1064,7 @@ SYM_CODE_START_LOCAL(error_entry)
|
|||
*/
|
||||
.Lerror_entry_done_lfence:
|
||||
FENCE_SWAPGS_KERNEL_ENTRY
|
||||
leaq 8(%rsp), %rax /* return pt_regs pointer */
|
||||
RET
|
||||
|
||||
.Lbstep_iret:
|
||||
|
|
@ -1059,7 +1077,7 @@ SYM_CODE_START_LOCAL(error_entry)
|
|||
* We came from an IRET to user mode, so we have user
|
||||
* gsbase and CR3. Switch to kernel gsbase and CR3:
|
||||
*/
|
||||
SWAPGS
|
||||
swapgs
|
||||
FENCE_SWAPGS_USER_ENTRY
|
||||
SWITCH_TO_KERNEL_CR3 scratch_reg=%rax
|
||||
|
||||
|
|
@ -1067,9 +1085,9 @@ SYM_CODE_START_LOCAL(error_entry)
|
|||
* Pretend that the exception came from user mode: set up pt_regs
|
||||
* as if we faulted immediately after IRET.
|
||||
*/
|
||||
mov %rsp, %rdi
|
||||
leaq 8(%rsp), %rdi /* arg0 = pt_regs pointer */
|
||||
call fixup_bad_iret
|
||||
mov %rax, %rsp
|
||||
mov %rax, %rdi
|
||||
jmp .Lerror_entry_from_usermode_after_swapgs
|
||||
SYM_CODE_END(error_entry)
|
||||
|
||||
|
|
@ -1132,6 +1150,7 @@ SYM_CODE_START(asm_exc_nmi)
|
|||
*/
|
||||
|
||||
ASM_CLAC
|
||||
cld
|
||||
|
||||
/* Use %rdx as our temp variable throughout */
|
||||
pushq %rdx
|
||||
|
|
@ -1151,7 +1170,6 @@ SYM_CODE_START(asm_exc_nmi)
|
|||
*/
|
||||
|
||||
swapgs
|
||||
cld
|
||||
FENCE_SWAPGS_USER_ENTRY
|
||||
SWITCH_TO_KERNEL_CR3 scratch_reg=%rdx
|
||||
movq %rsp, %rdx
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ SYM_CODE_START(entry_SYSENTER_compat)
|
|||
UNWIND_HINT_EMPTY
|
||||
ENDBR
|
||||
/* Interrupts are off on entry. */
|
||||
SWAPGS
|
||||
swapgs
|
||||
|
||||
pushq %rax
|
||||
SWITCH_TO_KERNEL_CR3 scratch_reg=%rax
|
||||
|
|
@ -83,32 +83,7 @@ SYM_INNER_LABEL(entry_SYSENTER_compat_after_hwframe, SYM_L_GLOBAL)
|
|||
movl %eax, %eax
|
||||
|
||||
pushq %rax /* pt_regs->orig_ax */
|
||||
pushq %rdi /* pt_regs->di */
|
||||
pushq %rsi /* pt_regs->si */
|
||||
pushq %rdx /* pt_regs->dx */
|
||||
pushq %rcx /* pt_regs->cx */
|
||||
pushq $-ENOSYS /* pt_regs->ax */
|
||||
pushq $0 /* pt_regs->r8 = 0 */
|
||||
xorl %r8d, %r8d /* nospec r8 */
|
||||
pushq $0 /* pt_regs->r9 = 0 */
|
||||
xorl %r9d, %r9d /* nospec r9 */
|
||||
pushq $0 /* pt_regs->r10 = 0 */
|
||||
xorl %r10d, %r10d /* nospec r10 */
|
||||
pushq $0 /* pt_regs->r11 = 0 */
|
||||
xorl %r11d, %r11d /* nospec r11 */
|
||||
pushq %rbx /* pt_regs->rbx */
|
||||
xorl %ebx, %ebx /* nospec rbx */
|
||||
pushq %rbp /* pt_regs->rbp (will be overwritten) */
|
||||
xorl %ebp, %ebp /* nospec rbp */
|
||||
pushq $0 /* pt_regs->r12 = 0 */
|
||||
xorl %r12d, %r12d /* nospec r12 */
|
||||
pushq $0 /* pt_regs->r13 = 0 */
|
||||
xorl %r13d, %r13d /* nospec r13 */
|
||||
pushq $0 /* pt_regs->r14 = 0 */
|
||||
xorl %r14d, %r14d /* nospec r14 */
|
||||
pushq $0 /* pt_regs->r15 = 0 */
|
||||
xorl %r15d, %r15d /* nospec r15 */
|
||||
|
||||
PUSH_AND_CLEAR_REGS rax=$-ENOSYS
|
||||
UNWIND_HINT_REGS
|
||||
|
||||
cld
|
||||
|
|
@ -225,35 +200,7 @@ SYM_INNER_LABEL(entry_SYSCALL_compat_safe_stack, SYM_L_GLOBAL)
|
|||
SYM_INNER_LABEL(entry_SYSCALL_compat_after_hwframe, SYM_L_GLOBAL)
|
||||
movl %eax, %eax /* discard orig_ax high bits */
|
||||
pushq %rax /* pt_regs->orig_ax */
|
||||
pushq %rdi /* pt_regs->di */
|
||||
pushq %rsi /* pt_regs->si */
|
||||
xorl %esi, %esi /* nospec si */
|
||||
pushq %rdx /* pt_regs->dx */
|
||||
xorl %edx, %edx /* nospec dx */
|
||||
pushq %rbp /* pt_regs->cx (stashed in bp) */
|
||||
xorl %ecx, %ecx /* nospec cx */
|
||||
pushq $-ENOSYS /* pt_regs->ax */
|
||||
pushq $0 /* pt_regs->r8 = 0 */
|
||||
xorl %r8d, %r8d /* nospec r8 */
|
||||
pushq $0 /* pt_regs->r9 = 0 */
|
||||
xorl %r9d, %r9d /* nospec r9 */
|
||||
pushq $0 /* pt_regs->r10 = 0 */
|
||||
xorl %r10d, %r10d /* nospec r10 */
|
||||
pushq $0 /* pt_regs->r11 = 0 */
|
||||
xorl %r11d, %r11d /* nospec r11 */
|
||||
pushq %rbx /* pt_regs->rbx */
|
||||
xorl %ebx, %ebx /* nospec rbx */
|
||||
pushq %rbp /* pt_regs->rbp (will be overwritten) */
|
||||
xorl %ebp, %ebp /* nospec rbp */
|
||||
pushq $0 /* pt_regs->r12 = 0 */
|
||||
xorl %r12d, %r12d /* nospec r12 */
|
||||
pushq $0 /* pt_regs->r13 = 0 */
|
||||
xorl %r13d, %r13d /* nospec r13 */
|
||||
pushq $0 /* pt_regs->r14 = 0 */
|
||||
xorl %r14d, %r14d /* nospec r14 */
|
||||
pushq $0 /* pt_regs->r15 = 0 */
|
||||
xorl %r15d, %r15d /* nospec r15 */
|
||||
|
||||
PUSH_AND_CLEAR_REGS rcx=%rbp rax=$-ENOSYS
|
||||
UNWIND_HINT_REGS
|
||||
|
||||
movq %rsp, %rdi
|
||||
|
|
@ -367,54 +314,25 @@ SYM_CODE_START(entry_INT80_compat)
|
|||
|
||||
/* switch to thread stack expects orig_ax and rdi to be pushed */
|
||||
pushq %rax /* pt_regs->orig_ax */
|
||||
pushq %rdi /* pt_regs->di */
|
||||
|
||||
/* Need to switch before accessing the thread stack. */
|
||||
SWITCH_TO_KERNEL_CR3 scratch_reg=%rdi
|
||||
SWITCH_TO_KERNEL_CR3 scratch_reg=%rax
|
||||
|
||||
/* In the Xen PV case we already run on the thread stack. */
|
||||
ALTERNATIVE "", "jmp .Lint80_keep_stack", X86_FEATURE_XENPV
|
||||
|
||||
movq %rsp, %rdi
|
||||
movq %rsp, %rax
|
||||
movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp
|
||||
|
||||
pushq 6*8(%rdi) /* regs->ss */
|
||||
pushq 5*8(%rdi) /* regs->rsp */
|
||||
pushq 4*8(%rdi) /* regs->eflags */
|
||||
pushq 3*8(%rdi) /* regs->cs */
|
||||
pushq 2*8(%rdi) /* regs->ip */
|
||||
pushq 1*8(%rdi) /* regs->orig_ax */
|
||||
pushq (%rdi) /* pt_regs->di */
|
||||
pushq 5*8(%rax) /* regs->ss */
|
||||
pushq 4*8(%rax) /* regs->rsp */
|
||||
pushq 3*8(%rax) /* regs->eflags */
|
||||
pushq 2*8(%rax) /* regs->cs */
|
||||
pushq 1*8(%rax) /* regs->ip */
|
||||
pushq 0*8(%rax) /* regs->orig_ax */
|
||||
.Lint80_keep_stack:
|
||||
|
||||
pushq %rsi /* pt_regs->si */
|
||||
xorl %esi, %esi /* nospec si */
|
||||
pushq %rdx /* pt_regs->dx */
|
||||
xorl %edx, %edx /* nospec dx */
|
||||
pushq %rcx /* pt_regs->cx */
|
||||
xorl %ecx, %ecx /* nospec cx */
|
||||
pushq $-ENOSYS /* pt_regs->ax */
|
||||
pushq %r8 /* pt_regs->r8 */
|
||||
xorl %r8d, %r8d /* nospec r8 */
|
||||
pushq %r9 /* pt_regs->r9 */
|
||||
xorl %r9d, %r9d /* nospec r9 */
|
||||
pushq %r10 /* pt_regs->r10*/
|
||||
xorl %r10d, %r10d /* nospec r10 */
|
||||
pushq %r11 /* pt_regs->r11 */
|
||||
xorl %r11d, %r11d /* nospec r11 */
|
||||
pushq %rbx /* pt_regs->rbx */
|
||||
xorl %ebx, %ebx /* nospec rbx */
|
||||
pushq %rbp /* pt_regs->rbp */
|
||||
xorl %ebp, %ebp /* nospec rbp */
|
||||
pushq %r12 /* pt_regs->r12 */
|
||||
xorl %r12d, %r12d /* nospec r12 */
|
||||
pushq %r13 /* pt_regs->r13 */
|
||||
xorl %r13d, %r13d /* nospec r13 */
|
||||
pushq %r14 /* pt_regs->r14 */
|
||||
xorl %r14d, %r14d /* nospec r14 */
|
||||
pushq %r15 /* pt_regs->r15 */
|
||||
xorl %r15d, %r15d /* nospec r15 */
|
||||
|
||||
PUSH_AND_CLEAR_REGS rax=$-ENOSYS
|
||||
UNWIND_HINT_REGS
|
||||
|
||||
cld
|
||||
|
|
|
|||
|
|
@ -34,14 +34,17 @@ enum cpuid_leafs
|
|||
CPUID_8000_001F_EAX,
|
||||
};
|
||||
|
||||
#define X86_CAP_FMT_NUM "%d:%d"
|
||||
#define x86_cap_flag_num(flag) ((flag) >> 5), ((flag) & 31)
|
||||
|
||||
#ifdef CONFIG_X86_FEATURE_NAMES
|
||||
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]
|
||||
#else
|
||||
#define X86_CAP_FMT "%d:%d"
|
||||
#define x86_cap_flag(flag) ((flag) >> 5), ((flag) & 31)
|
||||
#define X86_CAP_FMT X86_CAP_FMT_NUM
|
||||
#define x86_cap_flag x86_cap_flag_num
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -10,12 +10,6 @@
|
|||
* cpu_feature_enabled().
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_X86_SMAP
|
||||
# define DISABLE_SMAP 0
|
||||
#else
|
||||
# define DISABLE_SMAP (1<<(X86_FEATURE_SMAP & 31))
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_UMIP
|
||||
# define DISABLE_UMIP 0
|
||||
#else
|
||||
|
|
@ -86,7 +80,7 @@
|
|||
#define DISABLED_MASK6 0
|
||||
#define DISABLED_MASK7 (DISABLE_PTI)
|
||||
#define DISABLED_MASK8 (DISABLE_TDX_GUEST)
|
||||
#define DISABLED_MASK9 (DISABLE_SMAP|DISABLE_SGX)
|
||||
#define DISABLED_MASK9 (DISABLE_SGX)
|
||||
#define DISABLED_MASK10 0
|
||||
#define DISABLED_MASK11 0
|
||||
#define DISABLED_MASK12 0
|
||||
|
|
|
|||
|
|
@ -137,14 +137,6 @@ static __always_inline void arch_local_irq_restore(unsigned long flags)
|
|||
if (!arch_irqs_disabled_flags(flags))
|
||||
arch_local_irq_enable();
|
||||
}
|
||||
#else
|
||||
#ifdef CONFIG_X86_64
|
||||
#ifdef CONFIG_XEN_PV
|
||||
#define SWAPGS ALTERNATIVE "swapgs", "", X86_FEATURE_XENPV
|
||||
#else
|
||||
#define SWAPGS swapgs
|
||||
#endif
|
||||
#endif
|
||||
#endif /* !__ASSEMBLY__ */
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ void xen_entry_INT80_compat(void);
|
|||
#endif
|
||||
|
||||
void x86_configure_nx(void);
|
||||
void x86_report_nx(void);
|
||||
|
||||
extern int reboot_force;
|
||||
|
||||
|
|
|
|||
|
|
@ -108,27 +108,19 @@ extern unsigned long _brk_end;
|
|||
void *extend_brk(size_t size, size_t align);
|
||||
|
||||
/*
|
||||
* Reserve space in the brk section. The name must be unique within
|
||||
* the file, and somewhat descriptive. The size is in bytes. Must be
|
||||
* used at file scope.
|
||||
* Reserve space in the brk section. The name must be unique within the file,
|
||||
* and somewhat descriptive. The size is in bytes.
|
||||
*
|
||||
* (This uses a temp function to wrap the asm so we can pass it the
|
||||
* size parameter; otherwise we wouldn't be able to. We can't use a
|
||||
* "section" attribute on a normal variable because it always ends up
|
||||
* being @progbits, which ends up allocating space in the vmlinux
|
||||
* executable.)
|
||||
* The allocation is done using inline asm (rather than using a section
|
||||
* attribute on a normal variable) in order to allow the use of @nobits, so
|
||||
* that it doesn't take up any space in the vmlinux file.
|
||||
*/
|
||||
#define RESERVE_BRK(name,sz) \
|
||||
static void __section(".discard.text") __noendbr __used notrace \
|
||||
__brk_reservation_fn_##name##__(void) { \
|
||||
asm volatile ( \
|
||||
".pushsection .brk_reservation,\"aw\",@nobits;" \
|
||||
".brk." #name ":" \
|
||||
" 1:.skip %c0;" \
|
||||
" .size .brk." #name ", . - 1b;" \
|
||||
" .popsection" \
|
||||
: : "i" (sz)); \
|
||||
}
|
||||
#define RESERVE_BRK(name, size) \
|
||||
asm(".pushsection .brk_reservation,\"aw\",@nobits\n\t" \
|
||||
".brk." #name ":\n\t" \
|
||||
".skip " __stringify(size) "\n\t" \
|
||||
".size .brk." #name ", " __stringify(size) "\n\t" \
|
||||
".popsection\n\t")
|
||||
|
||||
extern void probe_roms(void);
|
||||
#ifdef __i386__
|
||||
|
|
|
|||
|
|
@ -19,25 +19,14 @@
|
|||
|
||||
#ifdef __ASSEMBLY__
|
||||
|
||||
#ifdef CONFIG_X86_SMAP
|
||||
|
||||
#define ASM_CLAC \
|
||||
ALTERNATIVE "", __ASM_CLAC, X86_FEATURE_SMAP
|
||||
|
||||
#define ASM_STAC \
|
||||
ALTERNATIVE "", __ASM_STAC, X86_FEATURE_SMAP
|
||||
|
||||
#else /* CONFIG_X86_SMAP */
|
||||
|
||||
#define ASM_CLAC
|
||||
#define ASM_STAC
|
||||
|
||||
#endif /* CONFIG_X86_SMAP */
|
||||
|
||||
#else /* __ASSEMBLY__ */
|
||||
|
||||
#ifdef CONFIG_X86_SMAP
|
||||
|
||||
static __always_inline void clac(void)
|
||||
{
|
||||
/* Note: a barrier is implicit in alternative() */
|
||||
|
|
@ -76,19 +65,6 @@ static __always_inline void smap_restore(unsigned long flags)
|
|||
#define ASM_STAC \
|
||||
ALTERNATIVE("", __ASM_STAC, X86_FEATURE_SMAP)
|
||||
|
||||
#else /* CONFIG_X86_SMAP */
|
||||
|
||||
static inline void clac(void) { }
|
||||
static inline void stac(void) { }
|
||||
|
||||
static inline unsigned long smap_save(void) { return 0; }
|
||||
static inline void smap_restore(unsigned long flags) { }
|
||||
|
||||
#define ASM_CLAC
|
||||
#define ASM_STAC
|
||||
|
||||
#endif /* CONFIG_X86_SMAP */
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* _ASM_X86_SMAP_H */
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ struct saved_context {
|
|||
u16 gs;
|
||||
unsigned long cr0, cr2, cr3, cr4;
|
||||
u64 misc_enable;
|
||||
bool misc_enable_saved;
|
||||
struct saved_msrs saved_msrs;
|
||||
struct desc_ptr gdt_desc;
|
||||
struct desc_ptr idt;
|
||||
|
|
@ -28,6 +27,7 @@ struct saved_context {
|
|||
unsigned long tr;
|
||||
unsigned long safety;
|
||||
unsigned long return_address;
|
||||
bool misc_enable_saved;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* routines for saving/restoring kernel state */
|
||||
|
|
|
|||
|
|
@ -14,9 +14,13 @@
|
|||
* Image of the saved processor state, used by the low level ACPI suspend to
|
||||
* RAM code and by the low level hibernation code.
|
||||
*
|
||||
* If you modify it, fix arch/x86/kernel/acpi/wakeup_64.S and make sure that
|
||||
* __save/__restore_processor_state(), defined in arch/x86/kernel/suspend_64.c,
|
||||
* still work as required.
|
||||
* If you modify it, check how it is used in arch/x86/kernel/acpi/wakeup_64.S
|
||||
* and make sure that __save/__restore_processor_state(), defined in
|
||||
* arch/x86/power/cpu.c, still work as required.
|
||||
*
|
||||
* Because the structure is packed, make sure to avoid unaligned members. For
|
||||
* optimisation purposes but also because tools like kmemleak only search for
|
||||
* pointers that are aligned.
|
||||
*/
|
||||
struct saved_context {
|
||||
struct pt_regs regs;
|
||||
|
|
@ -36,7 +40,6 @@ struct saved_context {
|
|||
|
||||
unsigned long cr0, cr2, cr3, cr4;
|
||||
u64 misc_enable;
|
||||
bool misc_enable_saved;
|
||||
struct saved_msrs saved_msrs;
|
||||
unsigned long efer;
|
||||
u16 gdt_pad; /* Unused */
|
||||
|
|
@ -48,6 +51,7 @@ struct saved_context {
|
|||
unsigned long tr;
|
||||
unsigned long safety;
|
||||
unsigned long return_address;
|
||||
bool misc_enable_saved;
|
||||
} __attribute__((packed));
|
||||
|
||||
#define loaddebug(thread,register) \
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#ifdef CONFIG_X86_64
|
||||
asmlinkage __visible notrace struct pt_regs *sync_regs(struct pt_regs *eregs);
|
||||
asmlinkage __visible notrace
|
||||
struct bad_iret_stack *fixup_bad_iret(struct bad_iret_stack *s);
|
||||
struct pt_regs *fixup_bad_iret(struct pt_regs *bad_regs);
|
||||
void __init trap_init(void);
|
||||
asmlinkage __visible noinstr struct pt_regs *vc_switch_off_ist(struct pt_regs *eregs);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -446,6 +446,13 @@ void update_srbds_msr(void)
|
|||
if (srbds_mitigation == SRBDS_MITIGATION_UCODE_NEEDED)
|
||||
return;
|
||||
|
||||
/*
|
||||
* A MDS_NO CPU for which SRBDS mitigation is not needed due to TSX
|
||||
* being disabled and it hasn't received the SRBDS MSR microcode.
|
||||
*/
|
||||
if (!boot_cpu_has(X86_FEATURE_SRBDS_CTRL))
|
||||
return;
|
||||
|
||||
rdmsrl(MSR_IA32_MCU_OPT_CTRL, mcu_ctrl);
|
||||
|
||||
switch (srbds_mitigation) {
|
||||
|
|
|
|||
|
|
@ -299,13 +299,6 @@ static int __init cachesize_setup(char *str)
|
|||
}
|
||||
__setup("cachesize=", cachesize_setup);
|
||||
|
||||
static int __init x86_sep_setup(char *s)
|
||||
{
|
||||
setup_clear_cpu_cap(X86_FEATURE_SEP);
|
||||
return 1;
|
||||
}
|
||||
__setup("nosep", x86_sep_setup);
|
||||
|
||||
/* Standard macro to see if a specific flag is changeable */
|
||||
static inline int flag_is_changeable_p(u32 flag)
|
||||
{
|
||||
|
|
@ -377,26 +370,12 @@ static inline void squash_the_stupid_serial_number(struct cpuinfo_x86 *c)
|
|||
}
|
||||
#endif
|
||||
|
||||
static __init int setup_disable_smep(char *arg)
|
||||
{
|
||||
setup_clear_cpu_cap(X86_FEATURE_SMEP);
|
||||
return 1;
|
||||
}
|
||||
__setup("nosmep", setup_disable_smep);
|
||||
|
||||
static __always_inline void setup_smep(struct cpuinfo_x86 *c)
|
||||
{
|
||||
if (cpu_has(c, X86_FEATURE_SMEP))
|
||||
cr4_set_bits(X86_CR4_SMEP);
|
||||
}
|
||||
|
||||
static __init int setup_disable_smap(char *arg)
|
||||
{
|
||||
setup_clear_cpu_cap(X86_FEATURE_SMAP);
|
||||
return 1;
|
||||
}
|
||||
__setup("nosmap", setup_disable_smap);
|
||||
|
||||
static __always_inline void setup_smap(struct cpuinfo_x86 *c)
|
||||
{
|
||||
unsigned long eflags = native_save_fl();
|
||||
|
|
@ -404,14 +383,8 @@ static __always_inline void setup_smap(struct cpuinfo_x86 *c)
|
|||
/* This should have been cleared long ago */
|
||||
BUG_ON(eflags & X86_EFLAGS_AC);
|
||||
|
||||
if (cpu_has(c, X86_FEATURE_SMAP)) {
|
||||
#ifdef CONFIG_X86_SMAP
|
||||
if (cpu_has(c, X86_FEATURE_SMAP))
|
||||
cr4_set_bits(X86_CR4_SMAP);
|
||||
#else
|
||||
clear_cpu_cap(c, X86_FEATURE_SMAP);
|
||||
cr4_clear_bits(X86_CR4_SMAP);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static __always_inline void setup_umip(struct cpuinfo_x86 *c)
|
||||
|
|
@ -1369,8 +1342,8 @@ static void detect_nopl(void)
|
|||
static void __init cpu_parse_early_param(void)
|
||||
{
|
||||
char arg[128];
|
||||
char *argptr = arg;
|
||||
int arglen, res, bit;
|
||||
char *argptr = arg, *opt;
|
||||
int arglen, taint = 0;
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
if (cmdline_find_option_bool(boot_command_line, "no387"))
|
||||
|
|
@ -1398,21 +1371,61 @@ static void __init cpu_parse_early_param(void)
|
|||
return;
|
||||
|
||||
pr_info("Clearing CPUID bits:");
|
||||
do {
|
||||
res = get_option(&argptr, &bit);
|
||||
if (res == 0 || res == 3)
|
||||
break;
|
||||
|
||||
/* If the argument was too long, the last bit may be cut off */
|
||||
if (res == 1 && arglen >= sizeof(arg))
|
||||
break;
|
||||
while (argptr) {
|
||||
bool found __maybe_unused = false;
|
||||
unsigned int bit;
|
||||
|
||||
if (bit >= 0 && bit < NCAPINTS * 32) {
|
||||
pr_cont(" " X86_CAP_FMT, x86_cap_flag(bit));
|
||||
setup_clear_cpu_cap(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) {
|
||||
|
||||
#ifdef CONFIG_X86_FEATURE_NAMES
|
||||
/* empty-string, i.e., ""-defined feature flags */
|
||||
if (!x86_cap_flags[bit])
|
||||
pr_cont(" " X86_CAP_FMT_NUM, x86_cap_flag_num(bit));
|
||||
else
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
} while (res == 2);
|
||||
|
||||
#ifdef CONFIG_X86_FEATURE_NAMES
|
||||
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);
|
||||
#endif
|
||||
}
|
||||
pr_cont("\n");
|
||||
|
||||
if (taint)
|
||||
add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -1860,14 +1873,6 @@ void identify_secondary_cpu(struct cpuinfo_x86 *c)
|
|||
tsx_ap_init();
|
||||
}
|
||||
|
||||
static __init int setup_noclflush(char *arg)
|
||||
{
|
||||
setup_clear_cpu_cap(X86_FEATURE_CLFLUSH);
|
||||
setup_clear_cpu_cap(X86_FEATURE_CLFLUSHOPT);
|
||||
return 1;
|
||||
}
|
||||
__setup("noclflush", setup_noclflush);
|
||||
|
||||
void print_cpu_info(struct cpuinfo_x86 *c)
|
||||
{
|
||||
const char *vendor = NULL;
|
||||
|
|
|
|||
|
|
@ -756,6 +756,30 @@ dump_kernel_offset(struct notifier_block *self, unsigned long v, void *p)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void x86_configure_nx(void)
|
||||
{
|
||||
if (boot_cpu_has(X86_FEATURE_NX))
|
||||
__supported_pte_mask |= _PAGE_NX;
|
||||
else
|
||||
__supported_pte_mask &= ~_PAGE_NX;
|
||||
}
|
||||
|
||||
static void __init x86_report_nx(void)
|
||||
{
|
||||
if (!boot_cpu_has(X86_FEATURE_NX)) {
|
||||
printk(KERN_NOTICE "Notice: NX (Execute Disable) protection "
|
||||
"missing in CPU!\n");
|
||||
} else {
|
||||
#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
|
||||
printk(KERN_INFO "NX (Execute Disable) protection: active\n");
|
||||
#else
|
||||
/* 32bit non-PAE kernel, NX cannot be used */
|
||||
printk(KERN_NOTICE "Notice: NX (Execute Disable) protection "
|
||||
"cannot be enabled: non-PAE kernel!\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Determine if we were loaded by an EFI loader. If so, then we have also been
|
||||
* passed the efi memmap, systab, etc., so we should use these data structures
|
||||
|
|
@ -896,9 +920,7 @@ void __init setup_arch(char **cmdline_p)
|
|||
/*
|
||||
* x86_configure_nx() is called before parse_early_param() to detect
|
||||
* whether hardware doesn't support NX (so that the early EHCI debug
|
||||
* console setup can safely call set_fixmap()). It may then be called
|
||||
* again from within noexec_setup() during parsing early parameters
|
||||
* to honor the respective command line option.
|
||||
* console setup can safely call set_fixmap()).
|
||||
*/
|
||||
x86_configure_nx();
|
||||
|
||||
|
|
|
|||
|
|
@ -898,14 +898,10 @@ asmlinkage __visible noinstr struct pt_regs *vc_switch_off_ist(struct pt_regs *r
|
|||
}
|
||||
#endif
|
||||
|
||||
struct bad_iret_stack {
|
||||
void *error_entry_ret;
|
||||
struct pt_regs regs;
|
||||
};
|
||||
|
||||
asmlinkage __visible noinstr
|
||||
struct bad_iret_stack *fixup_bad_iret(struct bad_iret_stack *s)
|
||||
asmlinkage __visible noinstr struct pt_regs *fixup_bad_iret(struct pt_regs *bad_regs)
|
||||
{
|
||||
struct pt_regs tmp, *new_stack;
|
||||
|
||||
/*
|
||||
* This is called from entry_64.S early in handling a fault
|
||||
* caused by a bad iret to user mode. To handle the fault
|
||||
|
|
@ -914,19 +910,18 @@ struct bad_iret_stack *fixup_bad_iret(struct bad_iret_stack *s)
|
|||
* just below the IRET frame) and we want to pretend that the
|
||||
* exception came from the IRET target.
|
||||
*/
|
||||
struct bad_iret_stack tmp, *new_stack =
|
||||
(struct bad_iret_stack *)__this_cpu_read(cpu_tss_rw.x86_tss.sp0) - 1;
|
||||
new_stack = (struct pt_regs *)__this_cpu_read(cpu_tss_rw.x86_tss.sp0) - 1;
|
||||
|
||||
/* Copy the IRET target to the temporary storage. */
|
||||
__memcpy(&tmp.regs.ip, (void *)s->regs.sp, 5*8);
|
||||
__memcpy(&tmp.ip, (void *)bad_regs->sp, 5*8);
|
||||
|
||||
/* Copy the remainder of the stack from the current stack. */
|
||||
__memcpy(&tmp, s, offsetof(struct bad_iret_stack, regs.ip));
|
||||
__memcpy(&tmp, bad_regs, offsetof(struct pt_regs, ip));
|
||||
|
||||
/* Update the entry stack */
|
||||
__memcpy(new_stack, &tmp, sizeof(tmp));
|
||||
|
||||
BUG_ON(!user_mode(&new_stack->regs));
|
||||
BUG_ON(!user_mode(new_stack));
|
||||
return new_stack;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -20,13 +20,12 @@ CFLAGS_REMOVE_mem_encrypt_identity.o = -pg
|
|||
endif
|
||||
|
||||
obj-y := init.o init_$(BITS).o fault.o ioremap.o extable.o mmap.o \
|
||||
pgtable.o physaddr.o setup_nx.o tlb.o cpu_entry_area.o maccess.o
|
||||
pgtable.o physaddr.o tlb.o cpu_entry_area.o maccess.o
|
||||
|
||||
obj-y += pat/
|
||||
|
||||
# Make sure __phys_addr has no stackprotector
|
||||
CFLAGS_physaddr.o := -fno-stack-protector
|
||||
CFLAGS_setup_nx.o := -fno-stack-protector
|
||||
CFLAGS_mem_encrypt_identity.o := -fno-stack-protector
|
||||
|
||||
CFLAGS_fault.o := -I $(srctree)/$(src)/../include/asm/trace
|
||||
|
|
|
|||
|
|
@ -110,7 +110,6 @@ int force_personality32;
|
|||
/*
|
||||
* noexec32=on|off
|
||||
* Control non executable heap for 32bit processes.
|
||||
* To control the stack too use noexec=off
|
||||
*
|
||||
* on PROT_READ does not imply PROT_EXEC for 32-bit processes (default)
|
||||
* off PROT_READ implies PROT_EXEC
|
||||
|
|
|
|||
|
|
@ -1,62 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pgtable.h>
|
||||
|
||||
#include <asm/proto.h>
|
||||
#include <asm/cpufeature.h>
|
||||
|
||||
static int disable_nx;
|
||||
|
||||
/*
|
||||
* noexec = on|off
|
||||
*
|
||||
* Control non-executable mappings for processes.
|
||||
*
|
||||
* on Enable
|
||||
* off Disable
|
||||
*/
|
||||
static int __init noexec_setup(char *str)
|
||||
{
|
||||
if (!str)
|
||||
return -EINVAL;
|
||||
if (!strncmp(str, "on", 2)) {
|
||||
disable_nx = 0;
|
||||
} else if (!strncmp(str, "off", 3)) {
|
||||
disable_nx = 1;
|
||||
}
|
||||
x86_configure_nx();
|
||||
return 0;
|
||||
}
|
||||
early_param("noexec", noexec_setup);
|
||||
|
||||
void x86_configure_nx(void)
|
||||
{
|
||||
if (boot_cpu_has(X86_FEATURE_NX) && !disable_nx)
|
||||
__supported_pte_mask |= _PAGE_NX;
|
||||
else
|
||||
__supported_pte_mask &= ~_PAGE_NX;
|
||||
}
|
||||
|
||||
void __init x86_report_nx(void)
|
||||
{
|
||||
if (!boot_cpu_has(X86_FEATURE_NX)) {
|
||||
printk(KERN_NOTICE "Notice: NX (Execute Disable) protection "
|
||||
"missing in CPU!\n");
|
||||
} else {
|
||||
#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
|
||||
if (disable_nx) {
|
||||
printk(KERN_INFO "NX (Execute Disable) protection: "
|
||||
"disabled by kernel command line option\n");
|
||||
} else {
|
||||
printk(KERN_INFO "NX (Execute Disable) protection: "
|
||||
"active\n");
|
||||
}
|
||||
#else
|
||||
/* 32bit non-PAE kernel, NX cannot be used */
|
||||
printk(KERN_NOTICE "Notice: NX (Execute Disable) protection "
|
||||
"cannot be enabled: non-PAE kernel!\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -2085,6 +2085,8 @@ void bpf_offload_dev_netdev_unregister(struct bpf_offload_dev *offdev,
|
|||
struct net_device *netdev);
|
||||
bool bpf_offload_dev_match(struct bpf_prog *prog, struct net_device *netdev);
|
||||
|
||||
void unpriv_ebpf_notify(int new_state);
|
||||
|
||||
#if defined(CONFIG_NET) && defined(CONFIG_BPF_SYSCALL)
|
||||
int bpf_prog_offload_init(struct bpf_prog *prog, union bpf_attr *attr);
|
||||
|
||||
|
|
|
|||
|
|
@ -171,12 +171,9 @@
|
|||
|
||||
/* SYM_ALIAS -- use only if you have to */
|
||||
#ifndef SYM_ALIAS
|
||||
#define SYM_ALIAS(alias, name, sym_type, linkage) \
|
||||
linkage(alias) ASM_NL \
|
||||
.set alias, name ASM_NL \
|
||||
.type alias sym_type ASM_NL \
|
||||
.set .L__sym_size_##alias, .L__sym_size_##name ASM_NL \
|
||||
.size alias, .L__sym_size_##alias
|
||||
#define SYM_ALIAS(alias, name, linkage) \
|
||||
linkage(alias) ASM_NL \
|
||||
.set alias, name ASM_NL
|
||||
#endif
|
||||
|
||||
/* === code annotations === */
|
||||
|
|
@ -261,7 +258,7 @@
|
|||
*/
|
||||
#ifndef SYM_FUNC_ALIAS
|
||||
#define SYM_FUNC_ALIAS(alias, name) \
|
||||
SYM_ALIAS(alias, name, SYM_T_FUNC, SYM_L_GLOBAL)
|
||||
SYM_ALIAS(alias, name, SYM_L_GLOBAL)
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -269,7 +266,7 @@
|
|||
*/
|
||||
#ifndef SYM_FUNC_ALIAS_LOCAL
|
||||
#define SYM_FUNC_ALIAS_LOCAL(alias, name) \
|
||||
SYM_ALIAS(alias, name, SYM_T_FUNC, SYM_L_LOCAL)
|
||||
SYM_ALIAS(alias, name, SYM_L_LOCAL)
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -277,7 +274,7 @@
|
|||
*/
|
||||
#ifndef SYM_FUNC_ALIAS_WEAK
|
||||
#define SYM_FUNC_ALIAS_WEAK(alias, name) \
|
||||
SYM_ALIAS(alias, name, SYM_T_FUNC, SYM_L_WEAK)
|
||||
SYM_ALIAS(alias, name, SYM_L_WEAK)
|
||||
#endif
|
||||
|
||||
/* SYM_CODE_START -- use for non-C (special) functions */
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ struct unwind_hint {
|
|||
|
||||
#ifdef CONFIG_STACK_VALIDATION
|
||||
|
||||
#include <asm/asm.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#define UNWIND_HINT(sp_reg, sp_offset, type, end) \
|
||||
|
|
@ -137,7 +139,7 @@ struct unwind_hint {
|
|||
|
||||
.macro STACK_FRAME_NON_STANDARD func:req
|
||||
.pushsection .discard.func_stack_frame_non_standard, "aw"
|
||||
.long \func - .
|
||||
_ASM_PTR \func
|
||||
.popsection
|
||||
.endm
|
||||
|
||||
|
|
|
|||
18
kernel/configs/x86_debug.config
Normal file
18
kernel/configs/x86_debug.config
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
CONFIG_X86_DEBUG_FPU=y
|
||||
CONFIG_LOCK_STAT=y
|
||||
CONFIG_DEBUG_VM=y
|
||||
CONFIG_DEBUG_VM_VMACACHE=y
|
||||
CONFIG_DEBUG_VM_RB=y
|
||||
CONFIG_DEBUG_SLAB=y
|
||||
CONFIG_DEBUG_KMEMLEAK=y
|
||||
CONFIG_DEBUG_PAGEALLOC=y
|
||||
CONFIG_SLUB_DEBUG_ON=y
|
||||
CONFIG_KMEMCHECK=y
|
||||
CONFIG_DEBUG_OBJECTS=y
|
||||
CONFIG_DEBUG_OBJECTS_ENABLE_DEFAULT=1
|
||||
CONFIG_GCOV_KERNEL=y
|
||||
CONFIG_LOCKDEP=y
|
||||
CONFIG_PROVE_LOCKING=y
|
||||
CONFIG_SCHEDSTATS=y
|
||||
CONFIG_VMLINUX_VALIDATION=y
|
||||
CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y
|
||||
|
|
@ -233,7 +233,7 @@ objtool_args = \
|
|||
$(if $(CONFIG_FRAME_POINTER),, --no-fp) \
|
||||
$(if $(CONFIG_GCOV_KERNEL), --no-unreachable) \
|
||||
$(if $(CONFIG_RETPOLINE), --retpoline) \
|
||||
$(if $(CONFIG_X86_SMAP), --uaccess) \
|
||||
--uaccess \
|
||||
$(if $(CONFIG_FTRACE_MCOUNT_USE_OBJTOOL), --mcount) \
|
||||
$(if $(CONFIG_SLS), --sls)
|
||||
|
||||
|
|
|
|||
|
|
@ -146,9 +146,9 @@ objtool_link()
|
|||
if is_enabled CONFIG_RETPOLINE; then
|
||||
objtoolopt="${objtoolopt} --retpoline"
|
||||
fi
|
||||
if is_enabled CONFIG_X86_SMAP; then
|
||||
objtoolopt="${objtoolopt} --uaccess"
|
||||
fi
|
||||
|
||||
objtoolopt="${objtoolopt} --uaccess"
|
||||
|
||||
if is_enabled CONFIG_SLS; then
|
||||
objtoolopt="${objtoolopt} --sls"
|
||||
fi
|
||||
|
|
|
|||
|
|
@ -10,12 +10,6 @@
|
|||
* cpu_feature_enabled().
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_X86_SMAP
|
||||
# define DISABLE_SMAP 0
|
||||
#else
|
||||
# define DISABLE_SMAP (1<<(X86_FEATURE_SMAP & 31))
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_UMIP
|
||||
# define DISABLE_UMIP 0
|
||||
#else
|
||||
|
|
@ -80,7 +74,7 @@
|
|||
#define DISABLED_MASK6 0
|
||||
#define DISABLED_MASK7 (DISABLE_PTI)
|
||||
#define DISABLED_MASK8 0
|
||||
#define DISABLED_MASK9 (DISABLE_SMAP|DISABLE_SGX)
|
||||
#define DISABLED_MASK9 (DISABLE_SGX)
|
||||
#define DISABLED_MASK10 0
|
||||
#define DISABLED_MASK11 0
|
||||
#define DISABLED_MASK12 0
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ struct unwind_hint {
|
|||
|
||||
#ifdef CONFIG_STACK_VALIDATION
|
||||
|
||||
#include <asm/asm.h>
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#define UNWIND_HINT(sp_reg, sp_offset, type, end) \
|
||||
|
|
@ -137,7 +139,7 @@ struct unwind_hint {
|
|||
|
||||
.macro STACK_FRAME_NON_STANDARD func:req
|
||||
.pushsection .discard.func_stack_frame_non_standard, "aw"
|
||||
.long \func - .
|
||||
_ASM_PTR \func
|
||||
.popsection
|
||||
.endm
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user