#define X86_BUG_FXSAVE_LEAK    X86_BUG(6) /* FXSAVE leaks FOP/FIP/FOP */
 #define X86_BUG_CLFLUSH_MONITOR        X86_BUG(7) /* AAI65, CLFLUSH required before MONITOR */
 #define X86_BUG_SYSRET_SS_ATTRS        X86_BUG(8) /* SYSRET doesn't fix up SS attrs */
+#define X86_BUG_NULL_SEG       X86_BUG(9) /* Nulling a selector preserves the base */
 
 #ifdef CONFIG_X86_32
 /*
 
 #endif
 }
 
+static void detect_null_seg_behavior(struct cpuinfo_x86 *c)
+{
+#ifdef CONFIG_X86_64
+       /*
+        * Empirically, writing zero to a segment selector on AMD does
+        * not clear the base, whereas writing zero to a segment
+        * selector on Intel does clear the base.  Intel's behavior
+        * allows slightly faster context switches in the common case
+        * where GS is unused by the prev and next threads.
+        *
+        * Since neither vendor documents this anywhere that I can see,
+        * detect it directly instead of hardcoding the choice by
+        * vendor.
+        *
+        * I've designated AMD's behavior as the "bug" because it's
+        * counterintuitive and less friendly.
+        */
+
+       unsigned long old_base, tmp;
+       rdmsrl(MSR_FS_BASE, old_base);
+       wrmsrl(MSR_FS_BASE, 1);
+       loadsegment(fs, 0);
+       rdmsrl(MSR_FS_BASE, tmp);
+       if (tmp != 0)
+               set_cpu_bug(c, X86_BUG_NULL_SEG);
+       wrmsrl(MSR_FS_BASE, old_base);
+#endif
+}
+
 static void generic_identify(struct cpuinfo_x86 *c)
 {
        c->extended_cpuid_level = 0;
        get_model_name(c); /* Default name */
 
        detect_nopl(c);
+
+       detect_null_seg_behavior(c);
 }
 
 static void x86_init_cache_qos(struct cpuinfo_x86 *c)