[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v2 2/2] x86: correct fencing around CLFLUSH


  • To: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>
  • From: Jan Beulich <jbeulich@xxxxxxxx>
  • Date: Thu, 24 Feb 2022 14:24:59 +0100
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=suse.com; dmarc=pass action=none header.from=suse.com; dkim=pass header.d=suse.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=hJj7Nd1zQ5C3uR5AotGLWuOQOjAHBSXWP97Y2JLCbGE=; b=BadaGglrufTEw1s7lHHbwtwPce1gtObUFokR8nAC/P1du50v3FsuN+RfjtjfhyoLRJH7BSXcMYQ/QZxpgmoChXa/S80omn9GQ9PU4QBX/NdFr9JtQ3b7ubyxsEEzzFu1dVtUopd7N8FzFjXGtRQ3vXOc6eF4NSOdYk6oVQBGgkgIo1vxsiYlDQ8nH9OBUVLIBtX7albbmhA/NNkhcyeB+xjxgadDeqk0Ft2zLboHDG1Mi1yIx26kO7IO2oH6HntNkdrXUsyR5TY9CdjacShNYm172Rvtv51aGm2EW5lwLGi0u4gWASmtGH3qwG6jFR5wTQbPCwz/TCtlQXTXLi/RrA==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=BCOgu/EhVO5gB8Z0g8wfEuDIikrY2SN+Yt3tfCwfxziXFKa2RAeeLHoj2FtnDKkvp7mCc0JkcCGNIUMA62PwARkoq8Pc8XzOEf9nyCgLLVBun7EcgFPgirvtqUC3VvSnQyTmoCMQa/10lOkDAW1UZ3O2Uw1QnrE3K3nD+s2OEXI2AiJzDo/VN3Hw3jf62ZBLM0y+duU+Hm1nI4KMAlZhuLwRoFD1ahKkm3DhrYSZagUsZdi8eY50VDQoK2cKcxjLSu4xyRvivbgw1Tj5XovD9AyelMNOKR0sBKRDvK2A/e5YDHCBwrb8Ik/kiDuDsM/xRgSUf0GXnqdC8QxRDPIh2A==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=suse.com;
  • Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, Roger Pau Monné <roger.pau@xxxxxxxxxx>
  • Delivery-date: Thu, 24 Feb 2022 13:25:06 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>

As noted in the context of 3330013e6739 ("VT-d / x86: re-arrange cache
syncing"): While cache_writeback() has the SFENCE on the correct side of
CLFLUSHOPT, flush_area_local() doesn't. While I can't prove it due to
lacking a copy of the old SDM version, I can only assume this placement
was a result of what had been described there originally. In any event
recent versions of the SDM hve been telling us otherwise.

For AMD the situation is more complex: MFENCE is needed ahead and/or
after CLFLUSH when the CPU doesn't also support CLFLUSHOPT. (It's "and"
in the flush_area_local() case, as we cannot know what the caller's
needs are. For cache_writeback() fencing ahead of the flush is
sufficient.)

Fixes: 623c720fc8da3 ("x86: use CLFLUSHOPT when available")
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---
TBD: I'd be okay with not touching cache_writeback(), for only being
     used by VT-d right now.
---
v2: Mark AMD behavior as a bug rather than a feature. Retain quotes.

--- a/xen/arch/x86/cpu/amd.c
+++ b/xen/arch/x86/cpu/amd.c
@@ -761,6 +761,13 @@ static void __init noinline detect_bugs(
         */
        if (!cpu_has_nscb)
                setup_force_cpu_cap(X86_BUG_NULL_SEG);
+
+       /*
+        * AMD CPUs not supporting CLFLUSHOPT require MFENCE to serialize
+        * CLFLUSH against other memory accesses.
+        */
+       if (!cpu_has_clflushopt)
+               setup_force_cpu_cap(X86_BUG_CLFLUSH_MFENCE);
 }
 
 static void init_amd(struct cpuinfo_x86 *c)
--- a/xen/arch/x86/flushtlb.c
+++ b/xen/arch/x86/flushtlb.c
@@ -245,12 +245,15 @@ unsigned int flush_area_local(const void
              c->x86_clflush_size && c->x86_cache_size && sz &&
              ((sz >> 10) < c->x86_cache_size) )
         {
-            alternative("", "sfence", X86_FEATURE_CLFLUSHOPT);
+            alternative("", "mfence", X86_BUG_CLFLUSH_MFENCE);
             for ( i = 0; i < sz; i += c->x86_clflush_size )
                 alternative_input("ds; clflush %0",
                                   "data16 clflush %0",      /* clflushopt */
                                   X86_FEATURE_CLFLUSHOPT,
                                   "m" (((const char *)va)[i]));
+            alternative_2("",
+                          "sfence", X86_FEATURE_CLFLUSHOPT,
+                          "mfence", X86_BUG_CLFLUSH_MFENCE);
             flags &= ~FLUSH_CACHE;
         }
         else
@@ -274,6 +277,8 @@ void cache_writeback(const void *addr, u
     unsigned int clflush_size = current_cpu_data.x86_clflush_size ?: 16;
     const void *end = addr + size;
 
+    alternative("", "mfence", X86_BUG_CLFLUSH_MFENCE);
+
     addr -= (unsigned long)addr & (clflush_size - 1);
     for ( ; addr < end; addr += clflush_size )
     {
--- a/xen/arch/x86/include/asm/cpufeatures.h
+++ b/xen/arch/x86/include/asm/cpufeatures.h
@@ -47,6 +47,7 @@ XEN_CPUFEATURE(RET_SIMPLE,        X86_SY
 
 #define X86_BUG_FPU_PTRS          X86_BUG( 0) /* (F)X{SAVE,RSTOR} doesn't 
save/restore FOP/FIP/FDP. */
 #define X86_BUG_NULL_SEG          X86_BUG( 1) /* NULL-ing a selector preserves 
the base and limit. */
+#define X86_BUG_CLFLUSH_MFENCE    X86_BUG( 2) /* MFENCE needed to serialize 
CLFLUSH */
 
 /* Total number of capability words, inc synth and bug words. */
 #define NCAPINTS (FSCAPINTS + X86_NR_SYNTH + X86_NR_BUG) /* N 32-bit words 
worth of info */




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.