Skip to content

Commit 0fe5f9c

Browse files
committed
Merge tag 'x86-urgent-2020-04-19' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 and objtool fixes from Thomas Gleixner: "A set of fixes for x86 and objtool: objtool: - Ignore the double UD2 which is emitted in BUG() when CONFIG_UBSAN_TRAP is enabled. - Support clang non-section symbols in objtool ORC dump - Fix switch table detection in .text.unlikely - Make the BP scratch register warning more robust. x86: - Increase microcode maximum patch size for AMD to cope with new CPUs which have a larger patch size. - Fix a crash in the resource control filesystem when the removal of the default resource group is attempted. - Preserve Code and Data Prioritization enabled state accross CPU hotplug. - Update split lock cpu matching to use the new X86_MATCH macros. - Change the split lock enumeration as Intel finaly decided that the IA32_CORE_CAPABILITIES bits are not architectural contrary to what the SDM claims. !@#%$^! - Add Tremont CPU models to the split lock detection cpu match. - Add a missing static attribute to make sparse happy" * tag 'x86-urgent-2020-04-19' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/split_lock: Add Tremont family CPU models x86/split_lock: Bits in IA32_CORE_CAPABILITIES are not architectural x86/resctrl: Preserve CDP enable over CPU hotplug x86/resctrl: Fix invalid attempt at removing the default resource group x86/split_lock: Update to use X86_MATCH_INTEL_FAM6_MODEL() x86/umip: Make umip_insns static x86/microcode/AMD: Increase microcode PATCH_MAX_SIZE objtool: Make BP scratch register warning more robust objtool: Fix switch table detection in .text.unlikely objtool: Support Clang non-section symbols in ORC generation objtool: Support Clang non-section symbols in ORC dump objtool: Fix CONFIG_UBSAN_TRAP unreachable warnings
2 parents 3e0dea5 + 8b9a18a commit 0fe5f9c

File tree

9 files changed

+127
-53
lines changed

9 files changed

+127
-53
lines changed

arch/x86/include/asm/microcode_amd.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ struct microcode_amd {
4141
unsigned int mpb[0];
4242
};
4343

44-
#define PATCH_MAX_SIZE PAGE_SIZE
44+
#define PATCH_MAX_SIZE (3 * PAGE_SIZE)
4545

4646
#ifdef CONFIG_MICROCODE_AMD
4747
extern void __init load_ucode_amd_bsp(unsigned int family);

arch/x86/kernel/cpu/intel.c

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,35 +1119,53 @@ void switch_to_sld(unsigned long tifn)
11191119
sld_update_msr(!(tifn & _TIF_SLD));
11201120
}
11211121

1122-
#define SPLIT_LOCK_CPU(model) {X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY}
1123-
11241122
/*
1125-
* The following processors have the split lock detection feature. But
1126-
* since they don't have the IA32_CORE_CAPABILITIES MSR, the feature cannot
1127-
* be enumerated. Enable it by family and model matching on these
1128-
* processors.
1123+
* Bits in the IA32_CORE_CAPABILITIES are not architectural, so they should
1124+
* only be trusted if it is confirmed that a CPU model implements a
1125+
* specific feature at a particular bit position.
1126+
*
1127+
* The possible driver data field values:
1128+
*
1129+
* - 0: CPU models that are known to have the per-core split-lock detection
1130+
* feature even though they do not enumerate IA32_CORE_CAPABILITIES.
1131+
*
1132+
* - 1: CPU models which may enumerate IA32_CORE_CAPABILITIES and if so use
1133+
* bit 5 to enumerate the per-core split-lock detection feature.
11291134
*/
11301135
static const struct x86_cpu_id split_lock_cpu_ids[] __initconst = {
1131-
SPLIT_LOCK_CPU(INTEL_FAM6_ICELAKE_X),
1132-
SPLIT_LOCK_CPU(INTEL_FAM6_ICELAKE_L),
1136+
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_X, 0),
1137+
X86_MATCH_INTEL_FAM6_MODEL(ICELAKE_L, 0),
1138+
X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT, 1),
1139+
X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_D, 1),
1140+
X86_MATCH_INTEL_FAM6_MODEL(ATOM_TREMONT_L, 1),
11331141
{}
11341142
};
11351143

11361144
void __init cpu_set_core_cap_bits(struct cpuinfo_x86 *c)
11371145
{
1138-
u64 ia32_core_caps = 0;
1146+
const struct x86_cpu_id *m;
1147+
u64 ia32_core_caps;
1148+
1149+
if (boot_cpu_has(X86_FEATURE_HYPERVISOR))
1150+
return;
11391151

1140-
if (c->x86_vendor != X86_VENDOR_INTEL)
1152+
m = x86_match_cpu(split_lock_cpu_ids);
1153+
if (!m)
11411154
return;
1142-
if (cpu_has(c, X86_FEATURE_CORE_CAPABILITIES)) {
1143-
/* Enumerate features reported in IA32_CORE_CAPABILITIES MSR. */
1155+
1156+
switch (m->driver_data) {
1157+
case 0:
1158+
break;
1159+
case 1:
1160+
if (!cpu_has(c, X86_FEATURE_CORE_CAPABILITIES))
1161+
return;
11441162
rdmsrl(MSR_IA32_CORE_CAPS, ia32_core_caps);
1145-
} else if (!boot_cpu_has(X86_FEATURE_HYPERVISOR)) {
1146-
/* Enumerate split lock detection by family and model. */
1147-
if (x86_match_cpu(split_lock_cpu_ids))
1148-
ia32_core_caps |= MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT;
1163+
if (!(ia32_core_caps & MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT))
1164+
return;
1165+
break;
1166+
default:
1167+
return;
11491168
}
11501169

1151-
if (ia32_core_caps & MSR_IA32_CORE_CAPS_SPLIT_LOCK_DETECT)
1152-
split_lock_setup();
1170+
split_lock_setup();
11531171
}

arch/x86/kernel/cpu/resctrl/core.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,8 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r)
578578
d->id = id;
579579
cpumask_set_cpu(cpu, &d->cpu_mask);
580580

581+
rdt_domain_reconfigure_cdp(r);
582+
581583
if (r->alloc_capable && domain_setup_ctrlval(r, d)) {
582584
kfree(d);
583585
return;

arch/x86/kernel/cpu/resctrl/internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,5 +601,6 @@ bool has_busy_rmid(struct rdt_resource *r, struct rdt_domain *d);
601601
void __check_limbo(struct rdt_domain *d, bool force_free);
602602
bool cbm_validate_intel(char *buf, u32 *data, struct rdt_resource *r);
603603
bool cbm_validate_amd(char *buf, u32 *data, struct rdt_resource *r);
604+
void rdt_domain_reconfigure_cdp(struct rdt_resource *r);
604605

605606
#endif /* _ASM_X86_RESCTRL_INTERNAL_H */

arch/x86/kernel/cpu/resctrl/rdtgroup.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1859,6 +1859,19 @@ static int set_cache_qos_cfg(int level, bool enable)
18591859
return 0;
18601860
}
18611861

1862+
/* Restore the qos cfg state when a domain comes online */
1863+
void rdt_domain_reconfigure_cdp(struct rdt_resource *r)
1864+
{
1865+
if (!r->alloc_capable)
1866+
return;
1867+
1868+
if (r == &rdt_resources_all[RDT_RESOURCE_L2DATA])
1869+
l2_qos_cfg_update(&r->alloc_enabled);
1870+
1871+
if (r == &rdt_resources_all[RDT_RESOURCE_L3DATA])
1872+
l3_qos_cfg_update(&r->alloc_enabled);
1873+
}
1874+
18621875
/*
18631876
* Enable or disable the MBA software controller
18641877
* which helps user specify bandwidth in MBps.
@@ -3072,7 +3085,8 @@ static int rdtgroup_rmdir(struct kernfs_node *kn)
30723085
* If the rdtgroup is a mon group and parent directory
30733086
* is a valid "mon_groups" directory, remove the mon group.
30743087
*/
3075-
if (rdtgrp->type == RDTCTRL_GROUP && parent_kn == rdtgroup_default.kn) {
3088+
if (rdtgrp->type == RDTCTRL_GROUP && parent_kn == rdtgroup_default.kn &&
3089+
rdtgrp != &rdtgroup_default) {
30763090
if (rdtgrp->mode == RDT_MODE_PSEUDO_LOCKSETUP ||
30773091
rdtgrp->mode == RDT_MODE_PSEUDO_LOCKED) {
30783092
ret = rdtgroup_ctrl_remove(kn, rdtgrp);

arch/x86/kernel/umip.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@
8181
#define UMIP_INST_SLDT 3 /* 0F 00 /0 */
8282
#define UMIP_INST_STR 4 /* 0F 00 /1 */
8383

84-
const char * const umip_insns[5] = {
84+
static const char * const umip_insns[5] = {
8585
[UMIP_INST_SGDT] = "SGDT",
8686
[UMIP_INST_SIDT] = "SIDT",
8787
[UMIP_INST_SMSW] = "SMSW",

tools/objtool/check.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,10 +1050,7 @@ static struct rela *find_jump_table(struct objtool_file *file,
10501050
* it.
10511051
*/
10521052
for (;
1053-
&insn->list != &file->insn_list &&
1054-
insn->sec == func->sec &&
1055-
insn->offset >= func->offset;
1056-
1053+
&insn->list != &file->insn_list && insn->func && insn->func->pfunc == func;
10571054
insn = insn->first_jump_src ?: list_prev_entry(insn, list)) {
10581055

10591056
if (insn != orig_insn && insn->type == INSN_JUMP_DYNAMIC)
@@ -2008,8 +2005,8 @@ static int validate_return(struct symbol *func, struct instruction *insn, struct
20082005
}
20092006

20102007
if (state->bp_scratch) {
2011-
WARN("%s uses BP as a scratch register",
2012-
func->name);
2008+
WARN_FUNC("BP used as a scratch register",
2009+
insn->sec, insn->offset);
20132010
return 1;
20142011
}
20152012

@@ -2364,14 +2361,27 @@ static bool ignore_unreachable_insn(struct instruction *insn)
23642361
!strcmp(insn->sec->name, ".altinstr_aux"))
23652362
return true;
23662363

2364+
if (!insn->func)
2365+
return false;
2366+
2367+
/*
2368+
* CONFIG_UBSAN_TRAP inserts a UD2 when it sees
2369+
* __builtin_unreachable(). The BUG() macro has an unreachable() after
2370+
* the UD2, which causes GCC's undefined trap logic to emit another UD2
2371+
* (or occasionally a JMP to UD2).
2372+
*/
2373+
if (list_prev_entry(insn, list)->dead_end &&
2374+
(insn->type == INSN_BUG ||
2375+
(insn->type == INSN_JUMP_UNCONDITIONAL &&
2376+
insn->jump_dest && insn->jump_dest->type == INSN_BUG)))
2377+
return true;
2378+
23672379
/*
23682380
* Check if this (or a subsequent) instruction is related to
23692381
* CONFIG_UBSAN or CONFIG_KASAN.
23702382
*
23712383
* End the search at 5 instructions to avoid going into the weeds.
23722384
*/
2373-
if (!insn->func)
2374-
return false;
23752385
for (i = 0; i < 5; i++) {
23762386

23772387
if (is_kasan_insn(insn) || is_ubsan_insn(insn))

tools/objtool/orc_dump.c

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ int orc_dump(const char *_objname)
6666
char *name;
6767
size_t nr_sections;
6868
Elf64_Addr orc_ip_addr = 0;
69-
size_t shstrtab_idx;
69+
size_t shstrtab_idx, strtab_idx = 0;
7070
Elf *elf;
7171
Elf_Scn *scn;
7272
GElf_Shdr sh;
@@ -127,6 +127,8 @@ int orc_dump(const char *_objname)
127127

128128
if (!strcmp(name, ".symtab")) {
129129
symtab = data;
130+
} else if (!strcmp(name, ".strtab")) {
131+
strtab_idx = i;
130132
} else if (!strcmp(name, ".orc_unwind")) {
131133
orc = data->d_buf;
132134
orc_size = sh.sh_size;
@@ -138,7 +140,7 @@ int orc_dump(const char *_objname)
138140
}
139141
}
140142

141-
if (!symtab || !orc || !orc_ip)
143+
if (!symtab || !strtab_idx || !orc || !orc_ip)
142144
return 0;
143145

144146
if (orc_size % sizeof(*orc) != 0) {
@@ -159,21 +161,29 @@ int orc_dump(const char *_objname)
159161
return -1;
160162
}
161163

162-
scn = elf_getscn(elf, sym.st_shndx);
163-
if (!scn) {
164-
WARN_ELF("elf_getscn");
165-
return -1;
166-
}
167-
168-
if (!gelf_getshdr(scn, &sh)) {
169-
WARN_ELF("gelf_getshdr");
170-
return -1;
171-
}
172-
173-
name = elf_strptr(elf, shstrtab_idx, sh.sh_name);
174-
if (!name || !*name) {
175-
WARN_ELF("elf_strptr");
176-
return -1;
164+
if (GELF_ST_TYPE(sym.st_info) == STT_SECTION) {
165+
scn = elf_getscn(elf, sym.st_shndx);
166+
if (!scn) {
167+
WARN_ELF("elf_getscn");
168+
return -1;
169+
}
170+
171+
if (!gelf_getshdr(scn, &sh)) {
172+
WARN_ELF("gelf_getshdr");
173+
return -1;
174+
}
175+
176+
name = elf_strptr(elf, shstrtab_idx, sh.sh_name);
177+
if (!name) {
178+
WARN_ELF("elf_strptr");
179+
return -1;
180+
}
181+
} else {
182+
name = elf_strptr(elf, strtab_idx, sym.st_name);
183+
if (!name) {
184+
WARN_ELF("elf_strptr");
185+
return -1;
186+
}
177187
}
178188

179189
printf("%s+%llx:", name, (unsigned long long)rela.r_addend);

tools/objtool/orc_gen.c

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,6 @@ static int create_orc_entry(struct elf *elf, struct section *u_sec, struct secti
8888
struct orc_entry *orc;
8989
struct rela *rela;
9090

91-
if (!insn_sec->sym) {
92-
WARN("missing symbol for section %s", insn_sec->name);
93-
return -1;
94-
}
95-
9691
/* populate ORC data */
9792
orc = (struct orc_entry *)u_sec->data->d_buf + idx;
9893
memcpy(orc, o, sizeof(*orc));
@@ -105,8 +100,32 @@ static int create_orc_entry(struct elf *elf, struct section *u_sec, struct secti
105100
}
106101
memset(rela, 0, sizeof(*rela));
107102

108-
rela->sym = insn_sec->sym;
109-
rela->addend = insn_off;
103+
if (insn_sec->sym) {
104+
rela->sym = insn_sec->sym;
105+
rela->addend = insn_off;
106+
} else {
107+
/*
108+
* The Clang assembler doesn't produce section symbols, so we
109+
* have to reference the function symbol instead:
110+
*/
111+
rela->sym = find_symbol_containing(insn_sec, insn_off);
112+
if (!rela->sym) {
113+
/*
114+
* Hack alert. This happens when we need to reference
115+
* the NOP pad insn immediately after the function.
116+
*/
117+
rela->sym = find_symbol_containing(insn_sec,
118+
insn_off - 1);
119+
}
120+
if (!rela->sym) {
121+
WARN("missing symbol for insn at offset 0x%lx\n",
122+
insn_off);
123+
return -1;
124+
}
125+
126+
rela->addend = insn_off - rela->sym->offset;
127+
}
128+
110129
rela->type = R_X86_64_PC32;
111130
rela->offset = idx * sizeof(int);
112131
rela->sec = ip_relasec;

0 commit comments

Comments
 (0)