Merge tag 'x86-urgent-2020-12-06' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

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

- Make the AMD L3 QoS code and data priorization enable/disable
mechanism work correctly.

The control bit was only set/cleared on one of the CPUs in a L3
domain, but it has to be modified on all CPUs in the domain. The
initial documentation was not clear about this, but the updated one
from Oct 2020 spells it out.

- Fix an off by one in the UV platform detection code which causes
the UV hubs to be identified wrongly.

The chip revisions start at 1 not at 0.

- Fix a long standing bug in the evaluation of prefixes in the
uprobes code which fails to handle repeated prefixes properly.

The aggregate size of the prefixes can be larger than the bytes
array but the code blindly iterated over the aggregate size beyond
the array boundary. Add a macro to handle this case properly and
use it at the affected places"

* tag 'x86-urgent-2020-12-06' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/sev-es: Use new for_each_insn_prefix() macro to loop over prefixes bytes
x86/insn-eval: Use new for_each_insn_prefix() macro to loop over prefixes bytes
x86/uprobes: Do not use prefixes.nbytes when looping over prefixes.bytes
x86/platform/uv: Fix UV4 hub revision adjustment
x86/resctrl: Fix AMD L3 QOS CDP enable/disable

Changed files
+58 -15
arch
x86
boot
compressed
include
asm
kernel
lib
tools
arch
x86
include
asm
+2 -3
arch/x86/boot/compressed/sev-es.c
··· 32 32 */ 33 33 static bool insn_has_rep_prefix(struct insn *insn) 34 34 { 35 + insn_byte_t p; 35 36 int i; 36 37 37 38 insn_get_prefixes(insn); 38 39 39 - for (i = 0; i < insn->prefixes.nbytes; i++) { 40 - insn_byte_t p = insn->prefixes.bytes[i]; 41 - 40 + for_each_insn_prefix(insn, i, p) { 42 41 if (p == 0xf2 || p == 0xf3) 43 42 return true; 44 43 }
+15
arch/x86/include/asm/insn.h
··· 201 201 return insn_offset_displacement(insn) + insn->displacement.nbytes; 202 202 } 203 203 204 + /** 205 + * for_each_insn_prefix() -- Iterate prefixes in the instruction 206 + * @insn: Pointer to struct insn. 207 + * @idx: Index storage. 208 + * @prefix: Prefix byte. 209 + * 210 + * Iterate prefix bytes of given @insn. Each prefix byte is stored in @prefix 211 + * and the index is stored in @idx (note that this @idx is just for a cursor, 212 + * do not change it.) 213 + * Since prefixes.nbytes can be bigger than 4 if some prefixes 214 + * are repeated, it cannot be used for looping over the prefixes. 215 + */ 216 + #define for_each_insn_prefix(insn, idx, prefix) \ 217 + for (idx = 0; idx < ARRAY_SIZE(insn->prefixes.bytes) && (prefix = insn->prefixes.bytes[idx]) != 0; idx++) 218 + 204 219 #define POP_SS_OPCODE 0x1f 205 220 #define MOV_SREG_OPCODE 0x8e 206 221
+1 -1
arch/x86/kernel/apic/x2apic_uv_x.c
··· 161 161 /* UV4/4A only have a revision difference */ 162 162 case UV4_HUB_PART_NUMBER: 163 163 uv_min_hub_revision_id = node_id.s.revision 164 - + UV4_HUB_REVISION_BASE; 164 + + UV4_HUB_REVISION_BASE - 1; 165 165 uv_hub_type_set(UV4); 166 166 if (uv_min_hub_revision_id == UV4A_HUB_REVISION_BASE) 167 167 uv_hub_type_set(UV4|UV4A);
+4
arch/x86/kernel/cpu/resctrl/core.c
··· 570 570 571 571 if (d) { 572 572 cpumask_set_cpu(cpu, &d->cpu_mask); 573 + if (r->cache.arch_has_per_cpu_cfg) 574 + rdt_domain_reconfigure_cdp(r); 573 575 return; 574 576 } 575 577 ··· 925 923 r->rid == RDT_RESOURCE_L2CODE) { 926 924 r->cache.arch_has_sparse_bitmaps = false; 927 925 r->cache.arch_has_empty_bitmaps = false; 926 + r->cache.arch_has_per_cpu_cfg = false; 928 927 } else if (r->rid == RDT_RESOURCE_MBA) { 929 928 r->msr_base = MSR_IA32_MBA_THRTL_BASE; 930 929 r->msr_update = mba_wrmsr_intel; ··· 946 943 r->rid == RDT_RESOURCE_L2CODE) { 947 944 r->cache.arch_has_sparse_bitmaps = true; 948 945 r->cache.arch_has_empty_bitmaps = true; 946 + r->cache.arch_has_per_cpu_cfg = true; 949 947 } else if (r->rid == RDT_RESOURCE_MBA) { 950 948 r->msr_base = MSR_IA32_MBA_BW_BASE; 951 949 r->msr_update = mba_wrmsr_amd;
+3
arch/x86/kernel/cpu/resctrl/internal.h
··· 360 360 * executing entities 361 361 * @arch_has_sparse_bitmaps: True if a bitmap like f00f is valid. 362 362 * @arch_has_empty_bitmaps: True if the '0' bitmap is valid. 363 + * @arch_has_per_cpu_cfg: True if QOS_CFG register for this cache 364 + * level has CPU scope. 363 365 */ 364 366 struct rdt_cache { 365 367 unsigned int cbm_len; ··· 371 369 unsigned int shareable_bits; 372 370 bool arch_has_sparse_bitmaps; 373 371 bool arch_has_empty_bitmaps; 372 + bool arch_has_per_cpu_cfg; 374 373 }; 375 374 376 375 /**
+7 -2
arch/x86/kernel/cpu/resctrl/rdtgroup.c
··· 1909 1909 1910 1910 r_l = &rdt_resources_all[level]; 1911 1911 list_for_each_entry(d, &r_l->domains, list) { 1912 - /* Pick one CPU from each domain instance to update MSR */ 1913 - cpumask_set_cpu(cpumask_any(&d->cpu_mask), cpu_mask); 1912 + if (r_l->cache.arch_has_per_cpu_cfg) 1913 + /* Pick all the CPUs in the domain instance */ 1914 + for_each_cpu(cpu, &d->cpu_mask) 1915 + cpumask_set_cpu(cpu, cpu_mask); 1916 + else 1917 + /* Pick one CPU from each domain instance to update MSR */ 1918 + cpumask_set_cpu(cpumask_any(&d->cpu_mask), cpu_mask); 1914 1919 } 1915 1920 cpu = get_cpu(); 1916 1921 /* Update QOS_CFG MSR on this cpu if it's in cpu_mask. */
+6 -4
arch/x86/kernel/uprobes.c
··· 255 255 256 256 static bool is_prefix_bad(struct insn *insn) 257 257 { 258 + insn_byte_t p; 258 259 int i; 259 260 260 - for (i = 0; i < insn->prefixes.nbytes; i++) { 261 + for_each_insn_prefix(insn, i, p) { 261 262 insn_attr_t attr; 262 263 263 - attr = inat_get_opcode_attribute(insn->prefixes.bytes[i]); 264 + attr = inat_get_opcode_attribute(p); 264 265 switch (attr) { 265 266 case INAT_MAKE_PREFIX(INAT_PFX_ES): 266 267 case INAT_MAKE_PREFIX(INAT_PFX_CS): ··· 716 715 static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn) 717 716 { 718 717 u8 opc1 = OPCODE1(insn); 718 + insn_byte_t p; 719 719 int i; 720 720 721 721 switch (opc1) { ··· 748 746 * Intel and AMD behavior differ in 64-bit mode: Intel ignores 66 prefix. 749 747 * No one uses these insns, reject any branch insns with such prefix. 750 748 */ 751 - for (i = 0; i < insn->prefixes.nbytes; i++) { 752 - if (insn->prefixes.bytes[i] == 0x66) 749 + for_each_insn_prefix(insn, i, p) { 750 + if (p == 0x66) 753 751 return -ENOTSUPP; 754 752 } 755 753
+5 -5
arch/x86/lib/insn-eval.c
··· 63 63 */ 64 64 bool insn_has_rep_prefix(struct insn *insn) 65 65 { 66 + insn_byte_t p; 66 67 int i; 67 68 68 69 insn_get_prefixes(insn); 69 70 70 - for (i = 0; i < insn->prefixes.nbytes; i++) { 71 - insn_byte_t p = insn->prefixes.bytes[i]; 72 - 71 + for_each_insn_prefix(insn, i, p) { 73 72 if (p == 0xf2 || p == 0xf3) 74 73 return true; 75 74 } ··· 94 95 { 95 96 int idx = INAT_SEG_REG_DEFAULT; 96 97 int num_overrides = 0, i; 98 + insn_byte_t p; 97 99 98 100 insn_get_prefixes(insn); 99 101 100 102 /* Look for any segment override prefixes. */ 101 - for (i = 0; i < insn->prefixes.nbytes; i++) { 103 + for_each_insn_prefix(insn, i, p) { 102 104 insn_attr_t attr; 103 105 104 - attr = inat_get_opcode_attribute(insn->prefixes.bytes[i]); 106 + attr = inat_get_opcode_attribute(p); 105 107 switch (attr) { 106 108 case INAT_MAKE_PREFIX(INAT_PFX_CS): 107 109 idx = INAT_SEG_REG_CS;
+15
tools/arch/x86/include/asm/insn.h
··· 201 201 return insn_offset_displacement(insn) + insn->displacement.nbytes; 202 202 } 203 203 204 + /** 205 + * for_each_insn_prefix() -- Iterate prefixes in the instruction 206 + * @insn: Pointer to struct insn. 207 + * @idx: Index storage. 208 + * @prefix: Prefix byte. 209 + * 210 + * Iterate prefix bytes of given @insn. Each prefix byte is stored in @prefix 211 + * and the index is stored in @idx (note that this @idx is just for a cursor, 212 + * do not change it.) 213 + * Since prefixes.nbytes can be bigger than 4 if some prefixes 214 + * are repeated, it cannot be used for looping over the prefixes. 215 + */ 216 + #define for_each_insn_prefix(insn, idx, prefix) \ 217 + for (idx = 0; idx < ARRAY_SIZE(insn->prefixes.bytes) && (prefix = insn->prefixes.bytes[idx]) != 0; idx++) 218 + 204 219 #define POP_SS_OPCODE 0x1f 205 220 #define MOV_SREG_OPCODE 0x8e 206 221