Skip to content

Commit

Permalink
Merge tag 'x86-urgent-2020-11-08' of git://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/kernel/git/tip/tip

Pull x86 fixes from Thomas Gleixner:
 "A set of x86 fixes:

   - Use SYM_FUNC_START_WEAK in the mem* ASM functions instead of a
     combination of .weak and SYM_FUNC_START_LOCAL which makes LLVMs
     integrated assembler upset

   - Correct the mitigation selection logic which prevented the related
     prctl to work correctly

   - Make the UV5 hubless system work correctly by fixing up the
     malformed table entries and adding the missing ones"

* tag 'x86-urgent-2020-11-08' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/platform/uv: Recognize UV5 hubless system identifier
  x86/platform/uv: Remove spaces from OEM IDs
  x86/platform/uv: Fix missing OEM_TABLE_ID
  x86/speculation: Allow IBPB to be conditionally enabled on CPUs with always-on STIBP
  x86/lib: Change .weak to SYM_FUNC_START_WEAK for arch/x86/lib/mem*_64.S
  • Loading branch information
Linus Torvalds committed Nov 8, 2020
2 parents 100e389 + 801284f commit 40be821
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 32 deletions.
23 changes: 18 additions & 5 deletions arch/x86/kernel/apic/x2apic_uv_x.c
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,9 @@ static void __init uv_stringify(int len, char *to, char *from)
{
/* Relies on 'to' being NULL chars so result will be NULL terminated */
strncpy(to, from, len-1);

/* Trim trailing spaces */
(void)strim(to);
}

/* Find UV arch type entry in UVsystab */
Expand Down Expand Up @@ -366,7 +369,7 @@ static int __init early_get_arch_type(void)
return ret;
}

static int __init uv_set_system_type(char *_oem_id)
static int __init uv_set_system_type(char *_oem_id, char *_oem_table_id)
{
/* Save OEM_ID passed from ACPI MADT */
uv_stringify(sizeof(oem_id), oem_id, _oem_id);
Expand All @@ -386,13 +389,23 @@ static int __init uv_set_system_type(char *_oem_id)
/* (Not hubless), not a UV */
return 0;

/* Is UV hubless system */
uv_hubless_system = 0x01;

/* UV5 Hubless */
if (strncmp(uv_archtype, "NSGI5", 5) == 0)
uv_hubless_system |= 0x20;

/* UV4 Hubless: CH */
if (strncmp(uv_archtype, "NSGI4", 5) == 0)
uv_hubless_system = 0x11;
else if (strncmp(uv_archtype, "NSGI4", 5) == 0)
uv_hubless_system |= 0x10;

/* UV3 Hubless: UV300/MC990X w/o hub */
else
uv_hubless_system = 0x9;
uv_hubless_system |= 0x8;

/* Copy APIC type */
uv_stringify(sizeof(oem_table_id), oem_table_id, _oem_table_id);

pr_info("UV: OEM IDs %s/%s, SystemType %d, HUBLESS ID %x\n",
oem_id, oem_table_id, uv_system_type, uv_hubless_system);
Expand Down Expand Up @@ -456,7 +469,7 @@ static int __init uv_acpi_madt_oem_check(char *_oem_id, char *_oem_table_id)
uv_cpu_info->p_uv_hub_info = &uv_hub_info_node0;

/* If not UV, return. */
if (likely(uv_set_system_type(_oem_id) == 0))
if (uv_set_system_type(_oem_id, _oem_table_id) == 0)
return 0;

/* Save and Decode OEM Table ID */
Expand Down
51 changes: 33 additions & 18 deletions arch/x86/kernel/cpu/bugs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1254,23 +1254,41 @@ static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl)
return 0;
}

static bool is_spec_ib_user_controlled(void)
{
return spectre_v2_user_ibpb == SPECTRE_V2_USER_PRCTL ||
spectre_v2_user_ibpb == SPECTRE_V2_USER_SECCOMP ||
spectre_v2_user_stibp == SPECTRE_V2_USER_PRCTL ||
spectre_v2_user_stibp == SPECTRE_V2_USER_SECCOMP;
}

static int ib_prctl_set(struct task_struct *task, unsigned long ctrl)
{
switch (ctrl) {
case PR_SPEC_ENABLE:
if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE &&
spectre_v2_user_stibp == SPECTRE_V2_USER_NONE)
return 0;

/*
* Indirect branch speculation is always disabled in strict
* mode. It can neither be enabled if it was force-disabled
* by a previous prctl call.
* With strict mode for both IBPB and STIBP, the instruction
* code paths avoid checking this task flag and instead,
* unconditionally run the instruction. However, STIBP and IBPB
* are independent and either can be set to conditionally
* enabled regardless of the mode of the other.
*
* If either is set to conditional, allow the task flag to be
* updated, unless it was force-disabled by a previous prctl
* call. Currently, this is possible on an AMD CPU which has the
* feature X86_FEATURE_AMD_STIBP_ALWAYS_ON. In this case, if the
* kernel is booted with 'spectre_v2_user=seccomp', then
* spectre_v2_user_ibpb == SPECTRE_V2_USER_SECCOMP and
* spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED.
*/
if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT ||
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT ||
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED ||
if (!is_spec_ib_user_controlled() ||
task_spec_ib_force_disable(task))
return -EPERM;

task_clear_spec_ib_disable(task);
task_update_spec_tif(task);
break;
Expand All @@ -1283,10 +1301,10 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl)
if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE &&
spectre_v2_user_stibp == SPECTRE_V2_USER_NONE)
return -EPERM;
if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT ||
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT ||
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED)

if (!is_spec_ib_user_controlled())
return 0;

task_set_spec_ib_disable(task);
if (ctrl == PR_SPEC_FORCE_DISABLE)
task_set_spec_ib_force_disable(task);
Expand Down Expand Up @@ -1351,20 +1369,17 @@ static int ib_prctl_get(struct task_struct *task)
if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE &&
spectre_v2_user_stibp == SPECTRE_V2_USER_NONE)
return PR_SPEC_ENABLE;
else if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT ||
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT ||
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED)
return PR_SPEC_DISABLE;
else if (spectre_v2_user_ibpb == SPECTRE_V2_USER_PRCTL ||
spectre_v2_user_ibpb == SPECTRE_V2_USER_SECCOMP ||
spectre_v2_user_stibp == SPECTRE_V2_USER_PRCTL ||
spectre_v2_user_stibp == SPECTRE_V2_USER_SECCOMP) {
else if (is_spec_ib_user_controlled()) {
if (task_spec_ib_force_disable(task))
return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE;
if (task_spec_ib_disable(task))
return PR_SPEC_PRCTL | PR_SPEC_DISABLE;
return PR_SPEC_PRCTL | PR_SPEC_ENABLE;
} else
} else if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT ||
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT ||
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED)
return PR_SPEC_DISABLE;
else
return PR_SPEC_NOT_AFFECTED;
}

Expand Down
4 changes: 1 addition & 3 deletions arch/x86/lib/memcpy_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@
* to a jmp to memcpy_erms which does the REP; MOVSB mem copy.
*/

.weak memcpy

/*
* memcpy - Copy a memory block.
*
Expand All @@ -30,7 +28,7 @@
* rax original destination
*/
SYM_FUNC_START_ALIAS(__memcpy)
SYM_FUNC_START_LOCAL(memcpy)
SYM_FUNC_START_WEAK(memcpy)
ALTERNATIVE_2 "jmp memcpy_orig", "", X86_FEATURE_REP_GOOD, \
"jmp memcpy_erms", X86_FEATURE_ERMS

Expand Down
4 changes: 1 addition & 3 deletions arch/x86/lib/memmove_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@
* Output:
* rax: dest
*/
.weak memmove

SYM_FUNC_START_ALIAS(memmove)
SYM_FUNC_START_WEAK(memmove)
SYM_FUNC_START(__memmove)

mov %rdi, %rax
Expand Down
4 changes: 1 addition & 3 deletions arch/x86/lib/memset_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@
#include <asm/alternative-asm.h>
#include <asm/export.h>

.weak memset

/*
* ISO C memset - set a memory block to a byte value. This function uses fast
* string to get better performance than the original function. The code is
Expand All @@ -19,7 +17,7 @@
*
* rax original destination
*/
SYM_FUNC_START_ALIAS(memset)
SYM_FUNC_START_WEAK(memset)
SYM_FUNC_START(__memset)
/*
* Some CPUs support enhanced REP MOVSB/STOSB feature. It is recommended
Expand Down

0 comments on commit 40be821

Please sign in to comment.