|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH RFC 2/3] x86emul: support WBNOINVD
Rev 035 of Intel's ISA extensions document does not state intercept
behavior for the insn (I've been in-officially told that the distinction
is going to be by exit qualification, as I would have assumed
considering that this way it's sufficiently transparent to unaware
software, and using WBINVD in place of WBNOINVD is always correct, just
less efficient), so in the HVM case for now it'll be backed by the same
->wbinvd_intercept() handlers.
Use this occasion and also add the two missing table entries for
CLDEMOTE, which doesn't require any further changes to make work.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
--- a/tools/libxl/libxl_cpuid.c
+++ b/tools/libxl/libxl_cpuid.c
@@ -208,6 +208,7 @@ int libxl_cpuid_parse_config(libxl_cpuid
{"avx512-bitalg",0x00000007, 0, CPUID_REG_ECX, 12, 1},
{"avx512-vpopcntdq",0x00000007,0,CPUID_REG_ECX, 14, 1},
{"rdpid", 0x00000007, 0, CPUID_REG_ECX, 22, 1},
+ {"cldemote", 0x00000007, 0, CPUID_REG_ECX, 25, 1},
{"avx512-4vnniw",0x00000007, 0, CPUID_REG_EDX, 2, 1},
{"avx512-4fmaps",0x00000007, 0, CPUID_REG_EDX, 3, 1},
@@ -253,6 +254,7 @@ int libxl_cpuid_parse_config(libxl_cpuid
{"invtsc", 0x80000007, NA, CPUID_REG_EDX, 8, 1},
+ {"wbnoinvd", 0x80000008, NA, CPUID_REG_EBX, 9, 1},
{"ibpb", 0x80000008, NA, CPUID_REG_EBX, 12, 1},
{"nc", 0x80000008, NA, CPUID_REG_ECX, 0, 8},
{"apicidsize", 0x80000008, NA, CPUID_REG_ECX, 12, 4},
--- a/tools/misc/xen-cpuid.c
+++ b/tools/misc/xen-cpuid.c
@@ -146,6 +146,8 @@ static const char *str_e8b[32] =
{
[ 0] = "clzero",
+ /* [ 8] */ [ 9] = "wbnoinvd",
+
[12] = "ibpb",
};
--- a/xen/arch/x86/hvm/emulate.c
+++ b/xen/arch/x86/hvm/emulate.c
@@ -2177,6 +2177,7 @@ static int hvmemul_cache_management(
/* fall through */
case x86emul_invd:
case x86emul_wbinvd:
+ case x86emul_wbnoinvd:
hvm_funcs.wbinvd_intercept();
break;
}
--- a/xen/arch/x86/pv/emul-priv-op.c
+++ b/xen/arch/x86/pv/emul-priv-op.c
@@ -1135,7 +1135,7 @@ static int cache_management(enum x86emul
unsigned long offset,
struct x86_emulate_ctxt *ctxt)
{
- ASSERT(op == x86emul_wbinvd);
+ ASSERT(op == x86emul_wbinvd || op == x86emul_wbnoinvd);
/* Ignore the instruction if unprivileged. */
if ( !cache_flush_permitted(current->domain) )
@@ -1144,6 +1144,8 @@ static int cache_management(enum x86emul
* newer linux uses this in some start-of-day timing loops.
*/
;
+ else if ( op == x86emul_wbnoinvd && cpu_has_wbnoinvd )
+ wbnoinvd();
else
wbinvd();
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -1934,6 +1934,7 @@ static bool vcpu_has(
#define vcpu_has_avx512_4vnniw() vcpu_has( 7, EDX, 2, ctxt, ops)
#define vcpu_has_avx512_4fmaps() vcpu_has( 7, EDX, 3, ctxt, ops)
#define vcpu_has_clzero() vcpu_has(0x80000008, EBX, 0, ctxt, ops)
+#define vcpu_has_wbnoinvd() vcpu_has(0x80000008, EBX, 9, ctxt, ops)
#define vcpu_must_have(feat) \
generate_exception_if(!vcpu_has_##feat(), EXC_UD)
@@ -5957,10 +5958,13 @@ x86_emulate(
break;
case X86EMUL_OPC(0x0f, 0x08): /* invd */
- case X86EMUL_OPC(0x0f, 0x09): /* wbinvd */
+ case X86EMUL_OPC(0x0f, 0x09): /* wbinvd / wbnoinvd */
generate_exception_if(!mode_ring0(), EXC_GP, 0);
fail_if(!ops->cache_management);
- if ( (rc = ops->cache_management(b == 0x09 ? x86emul_wbinvd
+ if ( (rc = ops->cache_management(b == 0x09 ? !repe_prefix() ||
+ !vcpu_has_wbnoinvd()
+ ? x86emul_wbinvd
+ : x86emul_wbnoinvd
: x86emul_invd,
x86_seg_none, 0,
ctxt)) != X86EMUL_OKAY )
--- a/xen/arch/x86/x86_emulate/x86_emulate.h
+++ b/xen/arch/x86/x86_emulate/x86_emulate.h
@@ -182,6 +182,7 @@ enum x86emul_cache_op {
x86emul_clwb,
x86emul_invd,
x86emul_wbinvd,
+ x86emul_wbnoinvd,
};
struct x86_emulate_state;
--- a/xen/include/asm-x86/cpufeature.h
+++ b/xen/include/asm-x86/cpufeature.h
@@ -132,6 +132,9 @@
/* CPUID level 0x00000007:0.edx */
#define cpu_has_tsx_force_abort boot_cpu_has(X86_FEATURE_TSX_FORCE_ABORT)
+/* CPUID level 0x80000008.ebx */
+#define cpu_has_wbnoinvd boot_cpu_has(X86_FEATURE_WBNOINVD)
+
/* Synthesized. */
#define cpu_has_arch_perfmon boot_cpu_has(X86_FEATURE_ARCH_PERFMON)
#define cpu_has_cpuid_faulting boot_cpu_has(X86_FEATURE_CPUID_FAULTING)
--- a/xen/include/asm-x86/system.h
+++ b/xen/include/asm-x86/system.h
@@ -14,6 +14,9 @@
#define wbinvd() \
asm volatile ( "wbinvd" : : : "memory" )
+#define wbnoinvd() \
+ asm volatile ( "repe; wbinvd" : : : "memory" )
+
#define clflush(a) \
asm volatile ( "clflush (%0)" : : "r"(a) )
--- a/xen/include/public/arch-x86/cpufeatureset.h
+++ b/xen/include/public/arch-x86/cpufeatureset.h
@@ -236,6 +236,7 @@ XEN_CPUFEATURE(AVX512_VNNI, 6*32+11) /
XEN_CPUFEATURE(AVX512_BITALG, 6*32+12) /*A Support for VPOPCNT[B,W] and
VPSHUFBITQMB */
XEN_CPUFEATURE(AVX512_VPOPCNTDQ, 6*32+14) /*A POPCNT for vectors of DW/QW */
XEN_CPUFEATURE(RDPID, 6*32+22) /*A RDPID instruction */
+XEN_CPUFEATURE(CLDEMOTE, 6*32+25) /*A CLDEMOTE instruction */
/* AMD-defined CPU features, CPUID level 0x80000007.edx, word 7 */
XEN_CPUFEATURE(ITSC, 7*32+ 8) /* Invariant TSC */
@@ -243,6 +244,7 @@ XEN_CPUFEATURE(EFRO, 7*32+10) /
/* AMD-defined CPU features, CPUID level 0x80000008.ebx, word 8 */
XEN_CPUFEATURE(CLZERO, 8*32+ 0) /*A CLZERO instruction */
+XEN_CPUFEATURE(WBNOINVD, 8*32+ 9) /*A WBNOINVD instruction */
XEN_CPUFEATURE(IBPB, 8*32+12) /*A IBPB support only (no IBRS, used
by AMD) */
/* Intel-defined CPU features, CPUID level 0x00000007:0.edx, word 9 */
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |