[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH 2/2] x86/shskt: Disable CET-SS on parts succeptable to fractured updates
On Sat, Dec 31, 2022 at 12:30:07AM +0000, Andrew Cooper wrote: > Refer to Intel SDM Rev 70 (Dec 2022), Vol3 17.2.3 "Supervisor Shadow Stack > Token". > > Architecturally, an event delivery which starts in CPL>3 and switches shadow > stack will first validate the Supervisor Shstk Token and set the busy bit, > then pushes LIP/CS/SSP. One example of this is an NMI interrupting Xen. > > Some CPUs suffer from an issue called fracturing, whereby a fault/vmexit/etc > between setting the busy bit and completing the event injection renders the > action non-restartable, because when it comes time to restart, the busy bit is > found to be already set. > > This is far more easily encountered under virt, yet it is not the fault of the > hypervisor, nor the fault of the guest kernel. The fault lies somewhere > between the architectural specification, and the uarch behaviour. > > Intel have allocated CPUID.7[1].ecx[18] CET_SSS to enumerate that supervisor > shadow stacks are safe to use. Because of how Xen lays out its shadow stacks, > fracturing is not expected to be a problem on native. > > Detect this case on boot and default to not using shstk if virtualised. > Specifying `cet=shstk` on the command line will override this heurstic and > enable shadow stacks irrespective. > > Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> > --- > CC: Jan Beulich <JBeulich@xxxxxxxx> > CC: Roger Pau Monné <roger.pau@xxxxxxxxxx> > CC: Wei Liu <wl@xxxxxxx> > > I've got a query out with AMD, but so far it is only Intel CPUs known to be > impacted. > > This ideally wants backporting to Xen 4.14. I have no idea how likely it is > to need to backport the prerequisite patch for new feature words, but we've > already had to do that once for security patches... > --- > docs/misc/xen-command-line.pandoc | 7 +++++- > tools/libs/light/libxl_cpuid.c | 2 ++ > tools/misc/xen-cpuid.c | 1 + > xen/arch/x86/cpu/common.c | 11 +++++++-- > xen/arch/x86/setup.c | 37 > ++++++++++++++++++++++++++--- > xen/include/public/arch-x86/cpufeatureset.h | 1 + > 6 files changed, 53 insertions(+), 6 deletions(-) > > diff --git a/docs/misc/xen-command-line.pandoc > b/docs/misc/xen-command-line.pandoc > index 923910f553c5..19d4d815bdee 100644 > --- a/docs/misc/xen-command-line.pandoc > +++ b/docs/misc/xen-command-line.pandoc > @@ -287,10 +287,15 @@ can be maintained with the pv-shim mechanism. > protection. > > The option is available when `CONFIG_XEN_SHSTK` is compiled in, and > - defaults to `true` on hardware supporting CET-SS. Specifying > + generally defaults to `true` on hardware supporting CET-SS. Specifying > `cet=no-shstk` will cause Xen not to use Shadow Stacks even when support > is available in hardware. > > + Some hardware suffers from an issue known as Supervisor Shadow Stack > + Fracturing. On such hardware, Xen will default to not using Shadow > Stacks > + when virtualised. Specifying `cet=shstk` will override this heuristic > and > + enable Shadow Stacks unilaterally. > + > * The `ibt=` boolean controls whether Xen uses Indirect Branch Tracking for > its own protection. > > diff --git a/tools/libs/light/libxl_cpuid.c b/tools/libs/light/libxl_cpuid.c > index 2aa23225f42c..d97a2f3338bc 100644 > --- a/tools/libs/light/libxl_cpuid.c > +++ b/tools/libs/light/libxl_cpuid.c > @@ -235,6 +235,8 @@ int libxl_cpuid_parse_config(libxl_cpuid_policy_list > *cpuid, const char* str) > {"fsrs", 0x00000007, 1, CPUID_REG_EAX, 11, 1}, > {"fsrcs", 0x00000007, 1, CPUID_REG_EAX, 12, 1}, > > + {"cet-sss", 0x00000007, 1, CPUID_REG_EDX, 18, 1}, > + > {"intel-psfd", 0x00000007, 2, CPUID_REG_EDX, 0, 1}, > {"mcdt-no", 0x00000007, 2, CPUID_REG_EDX, 5, 1}, > > diff --git a/tools/misc/xen-cpuid.c b/tools/misc/xen-cpuid.c > index 0091a11a67bc..ea33b587665d 100644 > --- a/tools/misc/xen-cpuid.c > +++ b/tools/misc/xen-cpuid.c > @@ -208,6 +208,7 @@ static const char *const str_7c1[32] = > > static const char *const str_7d1[32] = > { > + [18] = "cet-sss", > }; > > static const char *const str_7d2[32] = > diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c > index b3fcf4680f3a..d962f384a995 100644 > --- a/xen/arch/x86/cpu/common.c > +++ b/xen/arch/x86/cpu/common.c > @@ -346,11 +346,18 @@ void __init early_cpu_init(void) > x86_cpuid_vendor_to_str(c->x86_vendor), c->x86, c->x86, > c->x86_model, c->x86_model, c->x86_mask, eax); > > - if (c->cpuid_level >= 7) > - cpuid_count(7, 0, &eax, &ebx, > + if (c->cpuid_level >= 7) { > + uint32_t max_subleaf; > + > + cpuid_count(7, 0, &max_subleaf, &ebx, > &c->x86_capability[FEATURESET_7c0], > &c->x86_capability[FEATURESET_7d0]); > > + if (max_subleaf >= 1) tabs vs spaces ... Is this file imported from Linux? It uses tabs for indentation, contrary to the rest of the Xen code base. > + cpuid_count(7, 1, &eax, &ebx, &ecx, > + &c->x86_capability[FEATURESET_7d1]); > + } > + > eax = cpuid_eax(0x80000000); > if ((eax >> 16) == 0x8000 && eax >= 0x80000008) { > ebx = eax >= 0x8000001f ? cpuid_ebx(0x8000001f) : 0; > diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c > index 566422600d94..e052b7b748fa 100644 > --- a/xen/arch/x86/setup.c > +++ b/xen/arch/x86/setup.c > @@ -96,7 +96,7 @@ size_param("highmem-start", highmem_start); > #endif > > #ifdef CONFIG_XEN_SHSTK > -static bool __initdata opt_xen_shstk = true; > +static int8_t __initdata opt_xen_shstk = -1; > #else > #define opt_xen_shstk false > #endif > @@ -1101,9 +1101,40 @@ void __init noreturn __start_xen(unsigned long mbi_p) > /* Choose shadow stack early, to set infrastructure up appropriately. */ > if ( opt_xen_shstk && boot_cpu_has(X86_FEATURE_CET_SS) ) > { > - printk("Enabling Supervisor Shadow Stacks\n"); > + /* > + * Some CPUs suffer from Shadow Stack Fracturing, an issue whereby a > + * fault/VMExit/etc between setting a Supervisor Busy bit and the > + * event delivery completing renders the operation non-restartable. > + * On restart, event delivery will find the Busy bit already set. > + * > + * This is a problem on native, but outside of synthetic cases, only > + * with #MC against a stack access (in which case we're dead anyway). > + * It is a much bigger problem under virt, because we can VMExit for > a > + * number of legitimate reasons and tickle this bug. > + * > + * CPUs with this addressed enumerate CET-SSS to indicate that > + * supervisor shadow stacks are now safe to use. > + */ > + bool cpu_has_bug_shstk_fracture = > + boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && > + !boot_cpu_has(X86_FEATURE_CET_SSS); > + > + /* > + * On native, assume that Xen won't be impacted by shstk fracturing > + * problems. Under virt, be more conservative and disable shstk by > + * default. > + */ > + if ( opt_xen_shstk == -1 ) > + opt_xen_shstk = > + cpu_has_hypervisor ? !cpu_has_bug_shstk_fracture > + : true; > + > + if ( opt_xen_shstk ) > + { > + printk("Enabling Supervisor Shadow Stacks\n"); > > - setup_force_cpu_cap(X86_FEATURE_XEN_SHSTK); > + setup_force_cpu_cap(X86_FEATURE_XEN_SHSTK); > + } > } > > if ( opt_xen_ibt && boot_cpu_has(X86_FEATURE_CET_IBT) ) > diff --git a/xen/include/public/arch-x86/cpufeatureset.h > b/xen/include/public/arch-x86/cpufeatureset.h > index 7a896f0e2d92..f6a46f62a549 100644 > --- a/xen/include/public/arch-x86/cpufeatureset.h > +++ b/xen/include/public/arch-x86/cpufeatureset.h > @@ -290,6 +290,7 @@ XEN_CPUFEATURE(INTEL_PPIN, 12*32+ 0) /* > Protected Processor Inventory > > /* Intel-defined CPU features, CPUID level 0x00000007:1.ecx, word 14 */ > /* Intel-defined CPU features, CPUID level 0x00000007:1.edx, word 15 */ > +XEN_CPUFEATURE(CET_SSS, 15*32+18) /* CET Supervisor Shadow > Stacks safe to use */ > > /* Intel-defined CPU features, CPUID level 0x00000007:2.edx, word 13 */ > XEN_CPUFEATURE(INTEL_PSFD, 13*32+ 0) /*A MSR_SPEC_CTRL.PSFD */ > -- > 2.11.0 > > -- Best Regards, Marek Marczykowski-Górecki Invisible Things Lab Attachment:
signature.asc
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |