Skip to content

Commit 5bb3a16

Browse files
committed
Merge tag 'x86_apic_for_v6.1_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 APIC update from Borislav Petkov: - Add support for locking the APIC in X2APIC mode to prevent SGX enclave leaks * tag 'x86_apic_for_v6.1_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/apic: Don't disable x2APIC if locked
2 parents 51eaa86 + b8d1d16 commit 5bb3a16

File tree

5 files changed

+65
-5
lines changed

5 files changed

+65
-5
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3805,6 +3805,10 @@
38053805

38063806
nox2apic [X86-64,APIC] Do not enable x2APIC mode.
38073807

3808+
NOTE: this parameter will be ignored on systems with the
3809+
LEGACY_XAPIC_DISABLED bit set in the
3810+
IA32_XAPIC_DISABLE_STATUS MSR.
3811+
38083812
nps_mtm_hs_ctr= [KNL,ARC]
38093813
This parameter sets the maximum duration, in
38103814
cycles, each HW thread of the CTOP can run

arch/x86/Kconfig

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,11 @@ config X86_X2APIC
451451
This allows 32-bit apic IDs (so it can support very large systems),
452452
and accesses the local apic via MSRs not via mmio.
453453

454+
Some Intel systems circa 2022 and later are locked into x2APIC mode
455+
and can not fall back to the legacy APIC modes if SGX or TDX are
456+
enabled in the BIOS. They will be unable to boot without enabling
457+
this option.
458+
454459
If you don't know what to do here, say N.
455460

456461
config X86_MPPARSE
@@ -1922,7 +1927,7 @@ endchoice
19221927

19231928
config X86_SGX
19241929
bool "Software Guard eXtensions (SGX)"
1925-
depends on X86_64 && CPU_SUP_INTEL
1930+
depends on X86_64 && CPU_SUP_INTEL && X86_X2APIC
19261931
depends on CRYPTO=y
19271932
depends on CRYPTO_SHA256=y
19281933
select SRCU

arch/x86/include/asm/cpu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,6 @@ static inline bool intel_cpu_signatures_match(unsigned int s1, unsigned int p1,
9494
return p1 & p2;
9595
}
9696

97+
extern u64 x86_read_arch_cap_msr(void);
98+
9799
#endif /* _ASM_X86_CPU_H */

arch/x86/include/asm/msr-index.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,11 @@
155155
* Return Stack Buffer Predictions.
156156
*/
157157

158+
#define ARCH_CAP_XAPIC_DISABLE BIT(21) /*
159+
* IA32_XAPIC_DISABLE_STATUS MSR
160+
* supported
161+
*/
162+
158163
#define MSR_IA32_FLUSH_CMD 0x0000010b
159164
#define L1D_FLUSH BIT(0) /*
160165
* Writeback and invalidate the
@@ -1054,4 +1059,12 @@
10541059
#define MSR_IA32_HW_FEEDBACK_PTR 0x17d0
10551060
#define MSR_IA32_HW_FEEDBACK_CONFIG 0x17d1
10561061

1062+
/* x2APIC locked status */
1063+
#define MSR_IA32_XAPIC_DISABLE_STATUS 0xBD
1064+
#define LEGACY_XAPIC_DISABLED BIT(0) /*
1065+
* x2APIC mode is locked and
1066+
* disabling x2APIC will cause
1067+
* a #GP
1068+
*/
1069+
10571070
#endif /* _ASM_X86_MSR_INDEX_H */

arch/x86/kernel/apic/apic.c

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
#include <asm/cpu_device_id.h>
6262
#include <asm/intel-family.h>
6363
#include <asm/irq_regs.h>
64+
#include <asm/cpu.h>
6465

6566
unsigned int num_processors;
6667

@@ -1751,11 +1752,26 @@ EXPORT_SYMBOL_GPL(x2apic_mode);
17511752

17521753
enum {
17531754
X2APIC_OFF,
1754-
X2APIC_ON,
17551755
X2APIC_DISABLED,
1756+
/* All states below here have X2APIC enabled */
1757+
X2APIC_ON,
1758+
X2APIC_ON_LOCKED
17561759
};
17571760
static int x2apic_state;
17581761

1762+
static bool x2apic_hw_locked(void)
1763+
{
1764+
u64 ia32_cap;
1765+
u64 msr;
1766+
1767+
ia32_cap = x86_read_arch_cap_msr();
1768+
if (ia32_cap & ARCH_CAP_XAPIC_DISABLE) {
1769+
rdmsrl(MSR_IA32_XAPIC_DISABLE_STATUS, msr);
1770+
return (msr & LEGACY_XAPIC_DISABLED);
1771+
}
1772+
return false;
1773+
}
1774+
17591775
static void __x2apic_disable(void)
17601776
{
17611777
u64 msr;
@@ -1793,6 +1809,10 @@ static int __init setup_nox2apic(char *str)
17931809
apicid);
17941810
return 0;
17951811
}
1812+
if (x2apic_hw_locked()) {
1813+
pr_warn("APIC locked in x2apic mode, can't disable\n");
1814+
return 0;
1815+
}
17961816
pr_warn("x2apic already enabled.\n");
17971817
__x2apic_disable();
17981818
}
@@ -1807,10 +1827,18 @@ early_param("nox2apic", setup_nox2apic);
18071827
void x2apic_setup(void)
18081828
{
18091829
/*
1810-
* If x2apic is not in ON state, disable it if already enabled
1830+
* Try to make the AP's APIC state match that of the BSP, but if the
1831+
* BSP is unlocked and the AP is locked then there is a state mismatch.
1832+
* Warn about the mismatch in case a GP fault occurs due to a locked AP
1833+
* trying to be turned off.
1834+
*/
1835+
if (x2apic_state != X2APIC_ON_LOCKED && x2apic_hw_locked())
1836+
pr_warn("x2apic lock mismatch between BSP and AP.\n");
1837+
/*
1838+
* If x2apic is not in ON or LOCKED state, disable it if already enabled
18111839
* from BIOS.
18121840
*/
1813-
if (x2apic_state != X2APIC_ON) {
1841+
if (x2apic_state < X2APIC_ON) {
18141842
__x2apic_disable();
18151843
return;
18161844
}
@@ -1831,6 +1859,11 @@ static __init void x2apic_disable(void)
18311859
if (x2apic_id >= 255)
18321860
panic("Cannot disable x2apic, id: %08x\n", x2apic_id);
18331861

1862+
if (x2apic_hw_locked()) {
1863+
pr_warn("Cannot disable locked x2apic, id: %08x\n", x2apic_id);
1864+
return;
1865+
}
1866+
18341867
__x2apic_disable();
18351868
register_lapic_address(mp_lapic_addr);
18361869
}
@@ -1889,7 +1922,10 @@ void __init check_x2apic(void)
18891922
if (x2apic_enabled()) {
18901923
pr_info("x2apic: enabled by BIOS, switching to x2apic ops\n");
18911924
x2apic_mode = 1;
1892-
x2apic_state = X2APIC_ON;
1925+
if (x2apic_hw_locked())
1926+
x2apic_state = X2APIC_ON_LOCKED;
1927+
else
1928+
x2apic_state = X2APIC_ON;
18931929
} else if (!boot_cpu_has(X86_FEATURE_X2APIC)) {
18941930
x2apic_state = X2APIC_DISABLED;
18951931
}

0 commit comments

Comments
 (0)