Skip to content

Commit 40be821

Browse files
committed
Merge tag 'x86-urgent-2020-11-08' of git://git.kernel.org/pub/scm/linux/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
2 parents 100e389 + 801284f commit 40be821

File tree

5 files changed

+54
-32
lines changed

5 files changed

+54
-32
lines changed

arch/x86/kernel/apic/x2apic_uv_x.c

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,9 @@ static void __init uv_stringify(int len, char *to, char *from)
290290
{
291291
/* Relies on 'to' being NULL chars so result will be NULL terminated */
292292
strncpy(to, from, len-1);
293+
294+
/* Trim trailing spaces */
295+
(void)strim(to);
293296
}
294297

295298
/* Find UV arch type entry in UVsystab */
@@ -366,7 +369,7 @@ static int __init early_get_arch_type(void)
366369
return ret;
367370
}
368371

369-
static int __init uv_set_system_type(char *_oem_id)
372+
static int __init uv_set_system_type(char *_oem_id, char *_oem_table_id)
370373
{
371374
/* Save OEM_ID passed from ACPI MADT */
372375
uv_stringify(sizeof(oem_id), oem_id, _oem_id);
@@ -386,13 +389,23 @@ static int __init uv_set_system_type(char *_oem_id)
386389
/* (Not hubless), not a UV */
387390
return 0;
388391

392+
/* Is UV hubless system */
393+
uv_hubless_system = 0x01;
394+
395+
/* UV5 Hubless */
396+
if (strncmp(uv_archtype, "NSGI5", 5) == 0)
397+
uv_hubless_system |= 0x20;
398+
389399
/* UV4 Hubless: CH */
390-
if (strncmp(uv_archtype, "NSGI4", 5) == 0)
391-
uv_hubless_system = 0x11;
400+
else if (strncmp(uv_archtype, "NSGI4", 5) == 0)
401+
uv_hubless_system |= 0x10;
392402

393403
/* UV3 Hubless: UV300/MC990X w/o hub */
394404
else
395-
uv_hubless_system = 0x9;
405+
uv_hubless_system |= 0x8;
406+
407+
/* Copy APIC type */
408+
uv_stringify(sizeof(oem_table_id), oem_table_id, _oem_table_id);
396409

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

458471
/* If not UV, return. */
459-
if (likely(uv_set_system_type(_oem_id) == 0))
472+
if (uv_set_system_type(_oem_id, _oem_table_id) == 0)
460473
return 0;
461474

462475
/* Save and Decode OEM Table ID */

arch/x86/kernel/cpu/bugs.c

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,23 +1254,41 @@ static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl)
12541254
return 0;
12551255
}
12561256

1257+
static bool is_spec_ib_user_controlled(void)
1258+
{
1259+
return spectre_v2_user_ibpb == SPECTRE_V2_USER_PRCTL ||
1260+
spectre_v2_user_ibpb == SPECTRE_V2_USER_SECCOMP ||
1261+
spectre_v2_user_stibp == SPECTRE_V2_USER_PRCTL ||
1262+
spectre_v2_user_stibp == SPECTRE_V2_USER_SECCOMP;
1263+
}
1264+
12571265
static int ib_prctl_set(struct task_struct *task, unsigned long ctrl)
12581266
{
12591267
switch (ctrl) {
12601268
case PR_SPEC_ENABLE:
12611269
if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE &&
12621270
spectre_v2_user_stibp == SPECTRE_V2_USER_NONE)
12631271
return 0;
1272+
12641273
/*
1265-
* Indirect branch speculation is always disabled in strict
1266-
* mode. It can neither be enabled if it was force-disabled
1267-
* by a previous prctl call.
1274+
* With strict mode for both IBPB and STIBP, the instruction
1275+
* code paths avoid checking this task flag and instead,
1276+
* unconditionally run the instruction. However, STIBP and IBPB
1277+
* are independent and either can be set to conditionally
1278+
* enabled regardless of the mode of the other.
1279+
*
1280+
* If either is set to conditional, allow the task flag to be
1281+
* updated, unless it was force-disabled by a previous prctl
1282+
* call. Currently, this is possible on an AMD CPU which has the
1283+
* feature X86_FEATURE_AMD_STIBP_ALWAYS_ON. In this case, if the
1284+
* kernel is booted with 'spectre_v2_user=seccomp', then
1285+
* spectre_v2_user_ibpb == SPECTRE_V2_USER_SECCOMP and
1286+
* spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED.
12681287
*/
1269-
if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT ||
1270-
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT ||
1271-
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED ||
1288+
if (!is_spec_ib_user_controlled() ||
12721289
task_spec_ib_force_disable(task))
12731290
return -EPERM;
1291+
12741292
task_clear_spec_ib_disable(task);
12751293
task_update_spec_tif(task);
12761294
break;
@@ -1283,10 +1301,10 @@ static int ib_prctl_set(struct task_struct *task, unsigned long ctrl)
12831301
if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE &&
12841302
spectre_v2_user_stibp == SPECTRE_V2_USER_NONE)
12851303
return -EPERM;
1286-
if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT ||
1287-
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT ||
1288-
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED)
1304+
1305+
if (!is_spec_ib_user_controlled())
12891306
return 0;
1307+
12901308
task_set_spec_ib_disable(task);
12911309
if (ctrl == PR_SPEC_FORCE_DISABLE)
12921310
task_set_spec_ib_force_disable(task);
@@ -1351,20 +1369,17 @@ static int ib_prctl_get(struct task_struct *task)
13511369
if (spectre_v2_user_ibpb == SPECTRE_V2_USER_NONE &&
13521370
spectre_v2_user_stibp == SPECTRE_V2_USER_NONE)
13531371
return PR_SPEC_ENABLE;
1354-
else if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT ||
1355-
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT ||
1356-
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED)
1357-
return PR_SPEC_DISABLE;
1358-
else if (spectre_v2_user_ibpb == SPECTRE_V2_USER_PRCTL ||
1359-
spectre_v2_user_ibpb == SPECTRE_V2_USER_SECCOMP ||
1360-
spectre_v2_user_stibp == SPECTRE_V2_USER_PRCTL ||
1361-
spectre_v2_user_stibp == SPECTRE_V2_USER_SECCOMP) {
1372+
else if (is_spec_ib_user_controlled()) {
13621373
if (task_spec_ib_force_disable(task))
13631374
return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE;
13641375
if (task_spec_ib_disable(task))
13651376
return PR_SPEC_PRCTL | PR_SPEC_DISABLE;
13661377
return PR_SPEC_PRCTL | PR_SPEC_ENABLE;
1367-
} else
1378+
} else if (spectre_v2_user_ibpb == SPECTRE_V2_USER_STRICT ||
1379+
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT ||
1380+
spectre_v2_user_stibp == SPECTRE_V2_USER_STRICT_PREFERRED)
1381+
return PR_SPEC_DISABLE;
1382+
else
13681383
return PR_SPEC_NOT_AFFECTED;
13691384
}
13701385

arch/x86/lib/memcpy_64.S

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
* to a jmp to memcpy_erms which does the REP; MOVSB mem copy.
1717
*/
1818

19-
.weak memcpy
20-
2119
/*
2220
* memcpy - Copy a memory block.
2321
*
@@ -30,7 +28,7 @@
3028
* rax original destination
3129
*/
3230
SYM_FUNC_START_ALIAS(__memcpy)
33-
SYM_FUNC_START_LOCAL(memcpy)
31+
SYM_FUNC_START_WEAK(memcpy)
3432
ALTERNATIVE_2 "jmp memcpy_orig", "", X86_FEATURE_REP_GOOD, \
3533
"jmp memcpy_erms", X86_FEATURE_ERMS
3634

arch/x86/lib/memmove_64.S

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@
2424
* Output:
2525
* rax: dest
2626
*/
27-
.weak memmove
28-
29-
SYM_FUNC_START_ALIAS(memmove)
27+
SYM_FUNC_START_WEAK(memmove)
3028
SYM_FUNC_START(__memmove)
3129

3230
mov %rdi, %rax

arch/x86/lib/memset_64.S

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
#include <asm/alternative-asm.h>
77
#include <asm/export.h>
88

9-
.weak memset
10-
119
/*
1210
* ISO C memset - set a memory block to a byte value. This function uses fast
1311
* string to get better performance than the original function. The code is
@@ -19,7 +17,7 @@
1917
*
2018
* rax original destination
2119
*/
22-
SYM_FUNC_START_ALIAS(memset)
20+
SYM_FUNC_START_WEAK(memset)
2321
SYM_FUNC_START(__memset)
2422
/*
2523
* Some CPUs support enhanced REP MOVSB/STOSB feature. It is recommended

0 commit comments

Comments
 (0)