Skip to content

Commit c9f016e

Browse files
committed
Merge tag 'x86-urgent-2024-09-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Thomas Gleixner: - x2apic_disable() clears x2apic_state and x2apic_mode unconditionally, even when the state is X2APIC_ON_LOCKED, which prevents the kernel to disable it thereby creating inconsistent state. Reorder the logic so it actually works correctly - The XSTATE logic for handling LBR is incorrect as it assumes that XSAVES supports LBR when the CPU supports LBR. In fact both conditions need to be true. Otherwise the enablement of LBR in the IA32_XSS MSR fails and subsequently the machine crashes on the next XRSTORS operation because IA32_XSS is not initialized. Cache the XSTATE support bit during init and make the related functions use this cached information and the LBR CPU feature bit to cure this. - Cure a long standing bug in KASLR KASLR uses the full address space between PAGE_OFFSET and vaddr_end to randomize the starting points of the direct map, vmalloc and vmemmap regions. It thereby limits the size of the direct map by using the installed memory size plus an extra configurable margin for hot-plug memory. This limitation is done to gain more randomization space because otherwise only the holes between the direct map, vmalloc, vmemmap and vaddr_end would be usable for randomizing. The limited direct map size is not exposed to the rest of the kernel, so the memory hot-plug and resource management related code paths still operate under the assumption that the available address space can be determined with MAX_PHYSMEM_BITS. request_free_mem_region() allocates from (1 << MAX_PHYSMEM_BITS) - 1 downwards. That means the first allocation happens past the end of the direct map and if unlucky this address is in the vmalloc space, which causes high_memory to become greater than VMALLOC_START and consequently causes iounmap() to fail for valid ioremap addresses. Cure this by exposing the end of the direct map via PHYSMEM_END and use that for the memory hot-plug and resource management related places instead of relying on MAX_PHYSMEM_BITS. In the KASLR case PHYSMEM_END maps to a variable which is initialized by the KASLR initialization and otherwise it is based on MAX_PHYSMEM_BITS as before. - Prevent a data leak in mmio_read(). The TDVMCALL exposes the value of an initialized variabled on the stack to the VMM. The variable is only required as output value, so it does not have to exposed to the VMM in the first place. - Prevent an array overrun in the resource control code on systems with Sub-NUMA Clustering enabled because the code failed to adjust the index by the number of SNC nodes per L3 cache. * tag 'x86-urgent-2024-09-01' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/resctrl: Fix arch_mbm_* array overrun on SNC x86/tdx: Fix data leak in mmio_read() x86/kaslr: Expose and use the end of the physical memory address space x86/fpu: Avoid writing LBR bit to IA32_XSS unless supported x86/apic: Make x2apic_disable() work correctly
2 parents 3df9427 + a547a58 commit c9f016e

File tree

16 files changed

+70
-26
lines changed

16 files changed

+70
-26
lines changed

arch/x86/coco/tdx/tdx.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,6 @@ static bool mmio_read(int size, unsigned long addr, unsigned long *val)
389389
.r12 = size,
390390
.r13 = EPT_READ,
391391
.r14 = addr,
392-
.r15 = *val,
393392
};
394393

395394
if (__tdx_hypercall(&args))

arch/x86/include/asm/fpu/types.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,13 @@ struct fpu_state_config {
591591
* even without XSAVE support, i.e. legacy features FP + SSE
592592
*/
593593
u64 legacy_features;
594+
/*
595+
* @independent_features:
596+
*
597+
* Features that are supported by XSAVES, but not managed as part of
598+
* the FPU core, such as LBR
599+
*/
600+
u64 independent_features;
594601
};
595602

596603
/* FPU state configuration information */

arch/x86/include/asm/page_64.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ extern unsigned long phys_base;
1717
extern unsigned long page_offset_base;
1818
extern unsigned long vmalloc_base;
1919
extern unsigned long vmemmap_base;
20+
extern unsigned long physmem_end;
2021

2122
static __always_inline unsigned long __phys_addr_nodebug(unsigned long x)
2223
{

arch/x86/include/asm/pgtable_64_types.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,10 @@ extern unsigned int ptrs_per_p4d;
140140
# define VMEMMAP_START __VMEMMAP_BASE_L4
141141
#endif /* CONFIG_DYNAMIC_MEMORY_LAYOUT */
142142

143+
#ifdef CONFIG_RANDOMIZE_MEMORY
144+
# define PHYSMEM_END physmem_end
145+
#endif
146+
143147
/*
144148
* End of the region for which vmalloc page tables are pre-allocated.
145149
* For non-KMSAN builds, this is the same as VMALLOC_END.

arch/x86/include/asm/resctrl.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,6 @@ static inline void resctrl_sched_in(struct task_struct *tsk)
156156
__resctrl_sched_in(tsk);
157157
}
158158

159-
static inline u32 resctrl_arch_system_num_rmid_idx(void)
160-
{
161-
/* RMID are independent numbers for x86. num_rmid_idx == num_rmid */
162-
return boot_cpu_data.x86_cache_max_rmid + 1;
163-
}
164-
165159
static inline void resctrl_arch_rmid_idx_decode(u32 idx, u32 *closid, u32 *rmid)
166160
{
167161
*rmid = idx;

arch/x86/kernel/apic/apic.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1775,12 +1775,9 @@ static __init void apic_set_fixmap(bool read_apic);
17751775

17761776
static __init void x2apic_disable(void)
17771777
{
1778-
u32 x2apic_id, state = x2apic_state;
1778+
u32 x2apic_id;
17791779

1780-
x2apic_mode = 0;
1781-
x2apic_state = X2APIC_DISABLED;
1782-
1783-
if (state != X2APIC_ON)
1780+
if (x2apic_state < X2APIC_ON)
17841781
return;
17851782

17861783
x2apic_id = read_apic_id();
@@ -1793,6 +1790,10 @@ static __init void x2apic_disable(void)
17931790
}
17941791

17951792
__x2apic_disable();
1793+
1794+
x2apic_mode = 0;
1795+
x2apic_state = X2APIC_DISABLED;
1796+
17961797
/*
17971798
* Don't reread the APIC ID as it was already done from
17981799
* check_x2apic() and the APIC driver still is a x2APIC variant,

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,14 @@ struct rdt_hw_resource rdt_resources_all[] = {
119119
},
120120
};
121121

122+
u32 resctrl_arch_system_num_rmid_idx(void)
123+
{
124+
struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
125+
126+
/* RMID are independent numbers for x86. num_rmid_idx == num_rmid */
127+
return r->num_rmid;
128+
}
129+
122130
/*
123131
* cache_alloc_hsw_probe() - Have to probe for Intel haswell server CPUs
124132
* as they do not have CPUID enumeration support for Cache allocation.

arch/x86/kernel/fpu/xstate.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,9 @@ void __init fpu__init_system_xstate(unsigned int legacy_size)
788788
goto out_disable;
789789
}
790790

791+
fpu_kernel_cfg.independent_features = fpu_kernel_cfg.max_features &
792+
XFEATURE_MASK_INDEPENDENT;
793+
791794
/*
792795
* Clear XSAVE features that are disabled in the normal CPUID.
793796
*/

arch/x86/kernel/fpu/xstate.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ static inline u64 xfeatures_mask_supervisor(void)
6262
static inline u64 xfeatures_mask_independent(void)
6363
{
6464
if (!cpu_feature_enabled(X86_FEATURE_ARCH_LBR))
65-
return XFEATURE_MASK_INDEPENDENT & ~XFEATURE_MASK_LBR;
65+
return fpu_kernel_cfg.independent_features & ~XFEATURE_MASK_LBR;
6666

67-
return XFEATURE_MASK_INDEPENDENT;
67+
return fpu_kernel_cfg.independent_features;
6868
}
6969

7070
/* XSAVE/XRSTOR wrapper functions */

arch/x86/mm/init_64.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -958,8 +958,12 @@ static void update_end_of_memory_vars(u64 start, u64 size)
958958
int add_pages(int nid, unsigned long start_pfn, unsigned long nr_pages,
959959
struct mhp_params *params)
960960
{
961+
unsigned long end = ((start_pfn + nr_pages) << PAGE_SHIFT) - 1;
961962
int ret;
962963

964+
if (WARN_ON_ONCE(end > PHYSMEM_END))
965+
return -ERANGE;
966+
963967
ret = __add_pages(nid, start_pfn, nr_pages, params);
964968
WARN_ON_ONCE(ret);
965969

0 commit comments

Comments
 (0)