All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests
@ 2015-12-16 21:24 Andrew Cooper
  2015-12-16 21:24 ` [PATCH RFC 01/31] xen/public: Export featureset information in the public API Andrew Cooper
                   ` (30 more replies)
  0 siblings, 31 replies; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel
  Cc: Wei Liu, Ian Campbell, Andrew Cooper, Ian Jackson, Tim Deegan,
	Jan Beulich

Presented here is v1 of my work to improve cpuid levelling for guests.  This
series is very close to what is now present in XenServer trunk, and testing is
going well.

This series is available in git form at:
  http://xenbits.xen.org/git-http/people/andrewcoop/xen.git levelling-v1

This entire series is RFC because it is based on Xen 4.6 (plus some backports
of already-accepted content) rather than staging.  I will rebase onto staging
for v2.

The current cpuid code, both in the hypervisor and toolstack, has grown
organically for a very long time, and is flawed in many ways.  This series
focuses specifically on the fixing the bits pertaining to the visible
features, and I will be fixing other areas in future work (e.g. per-core,
per-package values, auditing of incoming migration values, etc.)

These changes alter the workflow of cpuid handling as follows:

Xen boots and evaluates its current capabilities.  It uses this information to
calculate the maximum featuresets it can provide to guests, and provides this
information for toolstack consumption.  A toolstack may then calculate a safe
set of features (taking into account migratability), and sets a guests cpuid
policy.  Xen then takes care of context switching the levelling state.

In particular, this means that PV guests may have different levels while
running on the same host, an option which was not previously generally
available.

Andrew Cooper (31):
  xen/public: Export featureset information in the public API
  tools/libxc: Use public/featureset.h for cpuid policy generation
  xen/x86: Store antifeatures inverted in a featureset
  xen/x86: Mask out unknown features from Xen's capabilities
  xen/x86: Collect more CPUID feature words
  xen/x86: Infrastructure to calculate guest featuresets
  xen/x86: Export host featureset via SYSCTL
  tools/stubs: Expose host featureset to userspace
  xen/x86: Calculate PV featureset
  xen/x86: Calculate HVM featureset
  xen/x86: Calculate Raw featureset
  tools: Utility for dealing with featuresets
  tools/libxc: Wire a featureset through to cpuid policy logic
  tools/libxc: Use featureset rather than guesswork
  x86: Generate deep dependencies of x86 features
  x86: Automatically generate known_features
  xen/x86: Clear dependent features when clearing a cpu cap
  xen/x86: Improve disabling of features which have dependencies
  tools/libxc: Sanitise guest featuresets
  x86: Improvements to in-hypervisor cpuid sanity checks
  x86/domctl: Break out logic to update domain state from cpuid
    information
  x86/cpu: Move set_cpumask() calls into c_early_init()
  xen/x86: Export cpuid levelling capabilities via SYSCTL
  tools/stubs: Expose host levelling capabilities to userspace
  xen/x86: Common infrastructure for levelling context switching
  xen/x86: Rework AMD masking MSR setup
  xen/x86: Rework Intel masking/faulting setup
  xen/x86: Context switch all levelling state in context_switch()
  x86/pv: Provide custom cpumasks for PV domains
  x86/domctl: Update PV domain cpumasks when setting cpuid policy
  tools/libxc: Calculate xstate cpuid leaf from guest information

 .gitignore                               |   2 +
 tools/libxc/Makefile                     |   6 +
 tools/libxc/include/xenctrl.h            |   8 +
 tools/libxc/xc_bitops.h                  |  12 +-
 tools/libxc/xc_cpufeature.h              | 145 ----------
 tools/libxc/xc_cpuid_x86.c               | 437 +++++++++++++++----------------
 tools/libxc/xc_misc.c                    |  41 +++
 tools/misc/Makefile                      |   6 +
 tools/misc/xen-cpuid.c                   | 392 +++++++++++++++++++++++++++
 tools/ocaml/libs/xc/xenctrl.ml           |   5 +
 tools/ocaml/libs/xc/xenctrl.mli          |   6 +
 tools/ocaml/libs/xc/xenctrl_stubs.c      |  55 ++++
 xen/arch/x86/Makefile                    |   2 +
 xen/arch/x86/apic.c                      |   4 +-
 xen/arch/x86/cpu/amd.c                   | 263 ++++++++++++-------
 xen/arch/x86/cpu/common.c                |  54 +++-
 xen/arch/x86/cpu/cpu.h                   |   2 +
 xen/arch/x86/cpu/intel.c                 | 239 ++++++++++-------
 xen/arch/x86/cpuid.c                     |  92 +++++++
 xen/arch/x86/cpuid/Makefile              |   6 +
 xen/arch/x86/cpuid/cpuid-private.h       |  93 +++++++
 xen/arch/x86/cpuid/cpuid.c               | 223 ++++++++++++++++
 xen/arch/x86/cpuid/gen-feature-deps.py   | 169 ++++++++++++
 xen/arch/x86/domain.c                    |  15 +-
 xen/arch/x86/domctl.c                    | 132 ++++++++--
 xen/arch/x86/hvm/hvm.c                   |  62 +++--
 xen/arch/x86/setup.c                     |   3 +
 xen/arch/x86/sysctl.c                    |  69 +++++
 xen/arch/x86/traps.c                     | 106 ++------
 xen/arch/x86/xstate.c                    |   7 +-
 xen/include/asm-x86/cpufeature.h         | 178 ++-----------
 xen/include/asm-x86/cpuid.h              |  25 ++
 xen/include/asm-x86/domain.h             |   2 +
 xen/include/asm-x86/processor.h          |  30 ++-
 xen/include/public/arch-x86/featureset.h | 214 +++++++++++++++
 xen/include/public/sysctl.h              |  53 ++++
 36 files changed, 2287 insertions(+), 871 deletions(-)
 delete mode 100644 tools/libxc/xc_cpufeature.h
 create mode 100644 tools/misc/xen-cpuid.c
 create mode 100644 xen/arch/x86/cpuid.c
 create mode 100644 xen/arch/x86/cpuid/Makefile
 create mode 100644 xen/arch/x86/cpuid/cpuid-private.h
 create mode 100644 xen/arch/x86/cpuid/cpuid.c
 create mode 100755 xen/arch/x86/cpuid/gen-feature-deps.py
 create mode 100644 xen/include/asm-x86/cpuid.h
 create mode 100644 xen/include/public/arch-x86/featureset.h

-- 
2.1.4

^ permalink raw reply	[flat|nested] 123+ messages in thread

* [PATCH RFC 01/31] xen/public: Export featureset information in the public API
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2015-12-22 16:28   ` Jan Beulich
  2015-12-16 21:24 ` [PATCH RFC 02/31] tools/libxc: Use public/featureset.h for cpuid policy generation Andrew Cooper
                   ` (29 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Tim Deegan, Ian Campbell, Jan Beulich

For the featureset to be a useful object, it needs a stable interpretation, a
property which is missing from the current hw_caps interface.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Tim Deegan <tim@xen.org>
CC: Ian Campbell <Ian.Campbell@citrix.com>
---
 xen/include/asm-x86/cpufeature.h         | 175 +++++-----------------------
 xen/include/public/arch-x86/featureset.h | 192 +++++++++++++++++++++++++++++++
 2 files changed, 218 insertions(+), 149 deletions(-)
 create mode 100644 xen/include/public/arch-x86/featureset.h

diff --git a/xen/include/asm-x86/cpufeature.h b/xen/include/asm-x86/cpufeature.h
index c5a3f16..87724a0 100644
--- a/xen/include/asm-x86/cpufeature.h
+++ b/xen/include/asm-x86/cpufeature.h
@@ -11,156 +11,33 @@
 
 #include <xen/const.h>
 
-#define NCAPINTS	8	/* N 32-bit words worth of info */
-
-/* Intel-defined CPU features, CPUID level 0x00000001 (edx), word 0 */
-#define X86_FEATURE_FPU		(0*32+ 0) /* Onboard FPU */
-#define X86_FEATURE_VME		(0*32+ 1) /* Virtual Mode Extensions */
-#define X86_FEATURE_DE		(0*32+ 2) /* Debugging Extensions */
-#define X86_FEATURE_PSE 	(0*32+ 3) /* Page Size Extensions */
-#define X86_FEATURE_TSC		(0*32+ 4) /* Time Stamp Counter */
-#define X86_FEATURE_MSR		(0*32+ 5) /* Model-Specific Registers, RDMSR, WRMSR */
-#define X86_FEATURE_PAE		(0*32+ 6) /* Physical Address Extensions */
-#define X86_FEATURE_MCE		(0*32+ 7) /* Machine Check Architecture */
-#define X86_FEATURE_CX8		(0*32+ 8) /* CMPXCHG8 instruction */
-#define X86_FEATURE_APIC	(0*32+ 9) /* Onboard APIC */
-#define X86_FEATURE_SEP		(0*32+11) /* SYSENTER/SYSEXIT */
-#define X86_FEATURE_MTRR	(0*32+12) /* Memory Type Range Registers */
-#define X86_FEATURE_PGE		(0*32+13) /* Page Global Enable */
-#define X86_FEATURE_MCA		(0*32+14) /* Machine Check Architecture */
-#define X86_FEATURE_CMOV	(0*32+15) /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */
-#define X86_FEATURE_PAT		(0*32+16) /* Page Attribute Table */
-#define X86_FEATURE_PSE36	(0*32+17) /* 36-bit PSEs */
-#define X86_FEATURE_PN		(0*32+18) /* Processor serial number */
-#define X86_FEATURE_CLFLSH	(0*32+19) /* Supports the CLFLUSH instruction */
-#define X86_FEATURE_DS		(0*32+21) /* Debug Store */
-#define X86_FEATURE_ACPI	(0*32+22) /* ACPI via MSR */
-#define X86_FEATURE_MMX		(0*32+23) /* Multimedia Extensions */
-#define X86_FEATURE_FXSR	(0*32+24) /* FXSAVE and FXRSTOR instructions (fast save and restore */
-				          /* of FPU context), and CR4.OSFXSR available */
-#define X86_FEATURE_XMM		(0*32+25) /* Streaming SIMD Extensions */
-#define X86_FEATURE_XMM2	(0*32+26) /* Streaming SIMD Extensions-2 */
-#define X86_FEATURE_SELFSNOOP	(0*32+27) /* CPU self snoop */
-#define X86_FEATURE_HT		(0*32+28) /* Hyper-Threading */
-#define X86_FEATURE_ACC		(0*32+29) /* Automatic clock control */
-#define X86_FEATURE_IA64	(0*32+30) /* IA-64 processor */
-#define X86_FEATURE_PBE		(0*32+31) /* Pending Break Enable */
-#define X86_FEATURE_3DNOW_ALT	(0*32+31) /* AMD nonstandard 3DNow (Aliases PBE) */
-
-/* AMD-defined CPU features, CPUID level 0x80000001, word 1 */
-/* Don't duplicate feature flags which are redundant with Intel! */
-#define X86_FEATURE_SYSCALL	(1*32+11) /* SYSCALL/SYSRET */
-#define X86_FEATURE_MP		(1*32+19) /* MP Capable. */
-#define X86_FEATURE_NX		(1*32+20) /* Execute Disable */
-#define X86_FEATURE_MMXEXT	(1*32+22) /* AMD MMX extensions */
-#define X86_FEATURE_FFXSR       (1*32+25) /* FFXSR instruction optimizations */
-#define X86_FEATURE_PAGE1GB	(1*32+26) /* 1Gb large page support */
-#define X86_FEATURE_RDTSCP	(1*32+27) /* RDTSCP */
-#define X86_FEATURE_LM		(1*32+29) /* Long Mode (x86-64) */
-#define X86_FEATURE_3DNOWEXT	(1*32+30) /* AMD 3DNow! extensions */
-#define X86_FEATURE_3DNOW	(1*32+31) /* 3DNow! */
-
-/* Intel-defined CPU features, CPUID level 0x0000000D:1 (eax), word 2 */
-#define X86_FEATURE_XSAVEOPT	(2*32+ 0) /* XSAVEOPT instruction. */
-#define X86_FEATURE_XSAVEC	(2*32+ 1) /* XSAVEC/XRSTORC instructions. */
-#define X86_FEATURE_XGETBV1	(2*32+ 2) /* XGETBV with %ecx=1. */
-#define X86_FEATURE_XSAVES	(2*32+ 3) /* XSAVES/XRSTORS instructions. */
-
-/* Other features, Linux-defined mapping, word 3 */
+#include <public/arch-x86/featureset.h>
+
+#define FSMAX XEN_NR_FEATURESET_ENTRIES
+#define NCAPINTS (FSMAX + 2) /* N 32-bit words worth of info */
+
+/* Other features, Linux-defined mapping, FSMAX+1 */
 /* This range is used for feature bits which conflict or are synthesized */
-#define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */
-#define X86_FEATURE_NONSTOP_TSC	(3*32+ 9) /* TSC does not stop in C states */
-#define X86_FEATURE_ARAT	(3*32+ 10) /* Always running APIC timer */
-#define X86_FEATURE_ARCH_PERFMON (3*32+11) /* Intel Architectural PerfMon */
-#define X86_FEATURE_TSC_RELIABLE (3*32+12) /* TSC is known to be reliable */
-#define X86_FEATURE_XTOPOLOGY    (3*32+13) /* cpu topology enum extensions */
-#define X86_FEATURE_CPUID_FAULTING (3*32+14) /* cpuid faulting */
-#define X86_FEATURE_CLFLUSH_MONITOR (3*32+15) /* clflush reqd with monitor */
-
-/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
-#define X86_FEATURE_XMM3	(4*32+ 0) /* Streaming SIMD Extensions-3 */
-#define X86_FEATURE_PCLMULQDQ	(4*32+ 1) /* Carry-less mulitplication */
-#define X86_FEATURE_DTES64	(4*32+ 2) /* 64-bit Debug Store */
-#define X86_FEATURE_MWAIT	(4*32+ 3) /* Monitor/Mwait support */
-#define X86_FEATURE_DSCPL	(4*32+ 4) /* CPL Qualified Debug Store */
-#define X86_FEATURE_VMXE	(4*32+ 5) /* Virtual Machine Extensions */
-#define X86_FEATURE_SMXE	(4*32+ 6) /* Safer Mode Extensions */
-#define X86_FEATURE_EST		(4*32+ 7) /* Enhanced SpeedStep */
-#define X86_FEATURE_TM2		(4*32+ 8) /* Thermal Monitor 2 */
-#define X86_FEATURE_SSSE3	(4*32+ 9) /* Supplemental Streaming SIMD Extensions-3 */
-#define X86_FEATURE_CID		(4*32+10) /* Context ID */
-#define X86_FEATURE_FMA		(4*32+12) /* Fused Multiply Add */
-#define X86_FEATURE_CX16        (4*32+13) /* CMPXCHG16B */
-#define X86_FEATURE_XTPR	(4*32+14) /* Send Task Priority Messages */
-#define X86_FEATURE_PDCM	(4*32+15) /* Perf/Debug Capability MSR */
-#define X86_FEATURE_PCID	(4*32+17) /* Process Context ID */
-#define X86_FEATURE_DCA		(4*32+18) /* Direct Cache Access */
-#define X86_FEATURE_SSE4_1	(4*32+19) /* Streaming SIMD Extensions 4.1 */
-#define X86_FEATURE_SSE4_2	(4*32+20) /* Streaming SIMD Extensions 4.2 */
-#define X86_FEATURE_X2APIC	(4*32+21) /* Extended xAPIC */
-#define X86_FEATURE_MOVBE	(4*32+22) /* movbe instruction */
-#define X86_FEATURE_POPCNT	(4*32+23) /* POPCNT instruction */
-#define X86_FEATURE_TSC_DEADLINE (4*32+24) /* "tdt" TSC Deadline Timer */
-#define X86_FEATURE_AES		(4*32+25) /* AES instructions */
-#define X86_FEATURE_XSAVE	(4*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */
-#define X86_FEATURE_OSXSAVE	(4*32+27) /* OSXSAVE */
-#define X86_FEATURE_AVX 	(4*32+28) /* Advanced Vector Extensions */
-#define X86_FEATURE_F16C 	(4*32+29) /* Half-precision convert instruction */
-#define X86_FEATURE_RDRAND 	(4*32+30) /* Digital Random Number Generator */
-#define X86_FEATURE_HYPERVISOR	(4*32+31) /* Running under some hypervisor */
-
-/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
-#define X86_FEATURE_XSTORE	(5*32+ 2) /* on-CPU RNG present (xstore insn) */
-#define X86_FEATURE_XSTORE_EN	(5*32+ 3) /* on-CPU RNG enabled */
-#define X86_FEATURE_XCRYPT	(5*32+ 6) /* on-CPU crypto (xcrypt insn) */
-#define X86_FEATURE_XCRYPT_EN	(5*32+ 7) /* on-CPU crypto enabled */
-#define X86_FEATURE_ACE2	(5*32+ 8) /* Advanced Cryptography Engine v2 */
-#define X86_FEATURE_ACE2_EN	(5*32+ 9) /* ACE v2 enabled */
-#define X86_FEATURE_PHE		(5*32+ 10) /* PadLock Hash Engine */
-#define X86_FEATURE_PHE_EN	(5*32+ 11) /* PHE enabled */
-#define X86_FEATURE_PMM		(5*32+ 12) /* PadLock Montgomery Multiplier */
-#define X86_FEATURE_PMM_EN	(5*32+ 13) /* PMM enabled */
-
-/* More extended AMD flags: CPUID level 0x80000001, ecx, word 6 */
-#define X86_FEATURE_LAHF_LM     (6*32+ 0) /* LAHF/SAHF in long mode */
-#define X86_FEATURE_CMP_LEGACY  (6*32+ 1) /* If yes HyperThreading not valid */
-#define X86_FEATURE_SVM         (6*32+ 2) /* Secure virtual machine */
-#define X86_FEATURE_EXTAPIC     (6*32+ 3) /* Extended APIC space */
-#define X86_FEATURE_CR8_LEGACY  (6*32+ 4) /* CR8 in 32-bit mode */
-#define X86_FEATURE_ABM         (6*32+ 5) /* Advanced bit manipulation */
-#define X86_FEATURE_SSE4A       (6*32+ 6) /* SSE-4A */
-#define X86_FEATURE_MISALIGNSSE (6*32+ 7) /* Misaligned SSE mode */
-#define X86_FEATURE_3DNOWPREFETCH (6*32+ 8) /* 3DNow prefetch instructions */
-#define X86_FEATURE_OSVW        (6*32+ 9) /* OS Visible Workaround */
-#define X86_FEATURE_IBS         (6*32+10) /* Instruction Based Sampling */
-#define X86_FEATURE_XOP         (6*32+11) /* extended AVX instructions */
-#define X86_FEATURE_SKINIT      (6*32+12) /* SKINIT/STGI instructions */
-#define X86_FEATURE_WDT         (6*32+13) /* Watchdog timer */
-#define X86_FEATURE_LWP         (6*32+15) /* Light Weight Profiling */
-#define X86_FEATURE_FMA4        (6*32+16) /* 4 operands MAC instructions */
-#define X86_FEATURE_NODEID_MSR  (6*32+19) /* NodeId MSR */
-#define X86_FEATURE_TBM         (6*32+21) /* trailing bit manipulations */
-#define X86_FEATURE_TOPOEXT     (6*32+22) /* topology extensions CPUID leafs */
-#define X86_FEATURE_DBEXT       (6*32+26) /* data breakpoint extension */
-#define X86_FEATURE_MWAITX      (6*32+29) /* MWAIT extension (MONITORX/MWAITX) */
-
-/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx), word 7 */
-#define X86_FEATURE_FSGSBASE	(7*32+ 0) /* {RD,WR}{FS,GS}BASE instructions */
-#define X86_FEATURE_BMI1	(7*32+ 3) /* 1st bit manipulation extensions */
-#define X86_FEATURE_HLE 	(7*32+ 4) /* Hardware Lock Elision */
-#define X86_FEATURE_AVX2	(7*32+ 5) /* AVX2 instructions */
-#define X86_FEATURE_SMEP	(7*32+ 7) /* Supervisor Mode Execution Protection */
-#define X86_FEATURE_BMI2	(7*32+ 8) /* 2nd bit manipulation extensions */
-#define X86_FEATURE_ERMS	(7*32+ 9) /* Enhanced REP MOVSB/STOSB */
-#define X86_FEATURE_INVPCID	(7*32+10) /* Invalidate Process Context ID */
-#define X86_FEATURE_RTM 	(7*32+11) /* Restricted Transactional Memory */
-#define X86_FEATURE_CMT 	(7*32+12) /* Cache Monitoring Technology */
-#define X86_FEATURE_NO_FPU_SEL 	(7*32+13) /* FPU CS/DS stored as zero */
-#define X86_FEATURE_MPX		(7*32+14) /* Memory Protection Extensions */
-#define X86_FEATURE_CAT 	(7*32+15) /* Cache Allocation Technology */
-#define X86_FEATURE_RDSEED	(7*32+18) /* RDSEED instruction */
-#define X86_FEATURE_ADX		(7*32+19) /* ADCX, ADOX instructions */
-#define X86_FEATURE_SMAP	(7*32+20) /* Supervisor Mode Access Prevention */
+#define X86_FEATURE_CONSTANT_TSC	((FSMAX+0)*32+ 8) /* TSC ticks at a constant rate */
+#define X86_FEATURE_NONSTOP_TSC		((FSMAX+0)*32+ 9) /* TSC does not stop in C states */
+#define X86_FEATURE_ARAT		((FSMAX+0)*32+10) /* Always running APIC timer */
+#define X86_FEATURE_ARCH_PERFMON	((FSMAX+0)*32+11) /* Intel Architectural PerfMon */
+#define X86_FEATURE_TSC_RELIABLE	((FSMAX+0)*32+12) /* TSC is known to be reliable */
+#define X86_FEATURE_XTOPOLOGY		((FSMAX+0)*32+13) /* cpu topology enum extensions */
+#define X86_FEATURE_CPUID_FAULTING	((FSMAX+0)*32+14) /* cpuid faulting */
+#define X86_FEATURE_CLFLUSH_MONITOR	((FSMAX+0)*32+15) /* clflush reqd with monitor */
+
+/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, FSMAX+2 */
+#define X86_FEATURE_XSTORE	((FSMAX+1)*32+ 2) /* on-CPU RNG present (xstore insn) */
+#define X86_FEATURE_XSTORE_EN	((FSMAX+1)*32+ 3) /* on-CPU RNG enabled */
+#define X86_FEATURE_XCRYPT	((FSMAX+1)*32+ 6) /* on-CPU crypto (xcrypt insn) */
+#define X86_FEATURE_XCRYPT_EN	((FSMAX+1)*32+ 7) /* on-CPU crypto enabled */
+#define X86_FEATURE_ACE2	((FSMAX+1)*32+ 8) /* Advanced Cryptography Engine v2 */
+#define X86_FEATURE_ACE2_EN	((FSMAX+1)*32+ 9) /* ACE v2 enabled */
+#define X86_FEATURE_PHE		((FSMAX+1)*32+10) /* PadLock Hash Engine */
+#define X86_FEATURE_PHE_EN	((FSMAX+1)*32+11) /* PHE enabled */
+#define X86_FEATURE_PMM		((FSMAX+1)*32+12) /* PadLock Montgomery Multiplier */
+#define X86_FEATURE_PMM_EN	((FSMAX+1)*32+13) /* PMM enabled */
 
 #define cpufeat_word(idx)	((idx) / 32)
 #define cpufeat_bit(idx)	((idx) % 32)
diff --git a/xen/include/public/arch-x86/featureset.h b/xen/include/public/arch-x86/featureset.h
new file mode 100644
index 0000000..9a01d10
--- /dev/null
+++ b/xen/include/public/arch-x86/featureset.h
@@ -0,0 +1,192 @@
+/*
+ * arch-x86/featureset.h
+ *
+ * Featureset definitions
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Copyright (c) 2015 Citrix Systems, Inc.
+ */
+
+#ifndef __XEN_PUBLIC_ARCH_X86_FEATURESET_H__
+#define __XEN_PUBLIC_ARCH_X86_FEATURESET_H__
+
+/*
+ * A featureset is a bitmap of x86 features, represented as a collection of
+ * 32bit words.
+ *
+ * Words are as specified in vendors programming manuals, and shall not
+ * contain any synthesied values.  New words may be added to the end of
+ * featureset.
+ *
+ * All featureset words currently originate from leaves specified for the
+ * CPUID instruction, but this is not preclude other sources of information.
+ */
+
+/*
+ * CPUID leaf shorthand:
+ * - optional 'e', Extended (0x8xxxxxxx)
+ * - leaf, uppercase hex
+ * - register, lowercase
+ * - optional subleaf, uppercase hex
+ */
+#define XEN_FEATURESET_1d     0 /* 0x00000001.edx      */
+#define XEN_FEATURESET_1c     1 /* 0x00000001.ecx      */
+#define XEN_FEATURESET_e1d    2 /* 0x80000001.edx      */
+#define XEN_FEATURESET_e1c    3 /* 0x80000001.ecx      */
+#define XEN_FEATURESET_Da1    4 /* 0x0000000d:1.eax    */
+#define XEN_FEATURESET_7b0    5 /* 0x00000007:0.ebx    */
+#define XEN_NR_FEATURESET_ENTRIES (XEN_FEATURESET_7b0 + 1)
+
+
+/* Intel-defined CPU features, CPUID level 0x00000001.edx, word 0 */
+#define X86_FEATURE_FPU           ( 0*32+ 0) /* Onboard FPU */
+#define X86_FEATURE_VME           ( 0*32+ 1) /* Virtual Mode Extensions */
+#define X86_FEATURE_DE            ( 0*32+ 2) /* Debugging Extensions */
+#define X86_FEATURE_PSE           ( 0*32+ 3) /* Page Size Extensions */
+#define X86_FEATURE_TSC           ( 0*32+ 4) /* Time Stamp Counter */
+#define X86_FEATURE_MSR           ( 0*32+ 5) /* Model-Specific Registers, RDMSR, WRMSR */
+#define X86_FEATURE_PAE           ( 0*32+ 6) /* Physical Address Extensions */
+#define X86_FEATURE_MCE           ( 0*32+ 7) /* Machine Check Architecture */
+#define X86_FEATURE_CX8           ( 0*32+ 8) /* CMPXCHG8 instruction */
+#define X86_FEATURE_APIC          ( 0*32+ 9) /* Onboard APIC */
+#define X86_FEATURE_SEP           ( 0*32+11) /* SYSENTER/SYSEXIT */
+#define X86_FEATURE_MTRR          ( 0*32+12) /* Memory Type Range Registers */
+#define X86_FEATURE_PGE           ( 0*32+13) /* Page Global Enable */
+#define X86_FEATURE_MCA           ( 0*32+14) /* Machine Check Architecture */
+#define X86_FEATURE_CMOV          ( 0*32+15) /* CMOV instruction (FCMOVCC and FCOMI too if FPU present) */
+#define X86_FEATURE_PAT           ( 0*32+16) /* Page Attribute Table */
+#define X86_FEATURE_PSE36         ( 0*32+17) /* 36-bit PSEs */
+#define X86_FEATURE_PN            ( 0*32+18) /* Processor serial number */
+#define X86_FEATURE_CLFLSH        ( 0*32+19) /* CLFLUSH instruction */
+#define X86_FEATURE_DS            ( 0*32+21) /* Debug Store */
+#define X86_FEATURE_ACPI          ( 0*32+22) /* ACPI via MSR */
+#define X86_FEATURE_MMX           ( 0*32+23) /* Multimedia Extensions */
+#define X86_FEATURE_FXSR          ( 0*32+24) /* FXSAVE and FXRSTOR instructions */
+#define X86_FEATURE_XMM           ( 0*32+25) /* Streaming SIMD Extensions */
+#define X86_FEATURE_XMM2          ( 0*32+26) /* Streaming SIMD Extensions-2 */
+#define X86_FEATURE_SELFSNOOP     ( 0*32+27) /* CPU self snoop */
+#define X86_FEATURE_HT            ( 0*32+28) /* Hyper-Threading */
+#define X86_FEATURE_ACC           ( 0*32+29) /* Automatic clock control */
+#define X86_FEATURE_IA64          ( 0*32+30) /* IA-64 processor */
+#define X86_FEATURE_PBE           ( 0*32+31) /* Pending Break Enable */
+#define X86_FEATURE_3DNOW_ALT     ( 0*32+31) /* AMD nonstandard 3DNow (Aliases PBE) */
+
+/* Intel-defined CPU features, CPUID level 0x00000001.ecx, word 1 */
+#define X86_FEATURE_XMM3          ( 1*32+ 0) /* Streaming SIMD Extensions-3 */
+#define X86_FEATURE_PCLMULQDQ     ( 1*32+ 1) /* Carry-less mulitplication */
+#define X86_FEATURE_DTES64        ( 1*32+ 2) /* 64-bit Debug Store */
+#define X86_FEATURE_MWAIT         ( 1*32+ 3) /* Monitor/Mwait support */
+#define X86_FEATURE_DSCPL         ( 1*32+ 4) /* CPL Qualified Debug Store */
+#define X86_FEATURE_VMXE          ( 1*32+ 5) /* Virtual Machine Extensions */
+#define X86_FEATURE_SMXE          ( 1*32+ 6) /* Safer Mode Extensions */
+#define X86_FEATURE_EST           ( 1*32+ 7) /* Enhanced SpeedStep */
+#define X86_FEATURE_TM2           ( 1*32+ 8) /* Thermal Monitor 2 */
+#define X86_FEATURE_SSSE3         ( 1*32+ 9) /* Supplemental Streaming SIMD Extensions-3 */
+#define X86_FEATURE_CID           ( 1*32+10) /* Context ID */
+#define X86_FEATURE_FMA           ( 1*32+12) /* Fused Multiply Add */
+#define X86_FEATURE_CX16          ( 1*32+13) /* CMPXCHG16B */
+#define X86_FEATURE_XTPR          ( 1*32+14) /* Send Task Priority Messages */
+#define X86_FEATURE_PDCM          ( 1*32+15) /* Perf/Debug Capability MSR */
+#define X86_FEATURE_PCID          ( 1*32+17) /* Process Context ID */
+#define X86_FEATURE_DCA           ( 1*32+18) /* Direct Cache Access */
+#define X86_FEATURE_SSE4_1        ( 1*32+19) /* Streaming SIMD Extensions 4.1 */
+#define X86_FEATURE_SSE4_2        ( 1*32+20) /* Streaming SIMD Extensions 4.2 */
+#define X86_FEATURE_X2APIC        ( 1*32+21) /* Extended xAPIC */
+#define X86_FEATURE_MOVBE         ( 1*32+22) /* movbe instruction */
+#define X86_FEATURE_POPCNT        ( 1*32+23) /* POPCNT instruction */
+#define X86_FEATURE_TSC_DEADLINE  ( 1*32+24) /* "tdt" TSC Deadline Timer */
+#define X86_FEATURE_AES           ( 1*32+25) /* AES instructions */
+#define X86_FEATURE_XSAVE         ( 1*32+26) /* XSAVE/XRSTOR/XSETBV/XGETBV */
+#define X86_FEATURE_OSXSAVE       ( 1*32+27) /* OSXSAVE */
+#define X86_FEATURE_AVX           ( 1*32+28) /* Advanced Vector Extensions */
+#define X86_FEATURE_F16C          ( 1*32+29) /* Half-precision convert instruction */
+#define X86_FEATURE_RDRAND        ( 1*32+30) /* Digital Random Number Generator */
+#define X86_FEATURE_HYPERVISOR    ( 1*32+31) /* Running under some hypervisor */
+
+/* AMD-defined CPU features, CPUID level 0x80000001.edx, word 2 */
+#define X86_FEATURE_SYSCALL       ( 2*32+11) /* SYSCALL/SYSRET */
+#define X86_FEATURE_MP            ( 2*32+19) /* MP Capable. */
+#define X86_FEATURE_NX            ( 2*32+20) /* Execute Disable */
+#define X86_FEATURE_MMXEXT        ( 2*32+22) /* AMD MMX extensions */
+#define X86_FEATURE_FFXSR         ( 2*32+25) /* FFXSR instruction optimizations */
+#define X86_FEATURE_PAGE1GB       ( 2*32+26) /* 1Gb large page support */
+#define X86_FEATURE_RDTSCP        ( 2*32+27) /* RDTSCP */
+#define X86_FEATURE_LM            ( 2*32+29) /* Long Mode (x86-64) */
+#define X86_FEATURE_3DNOWEXT      ( 2*32+30) /* AMD 3DNow! extensions */
+#define X86_FEATURE_3DNOW         ( 2*32+31) /* 3DNow! */
+
+/* AMD-defined CPU features, CPUID level 0x80000001.ecx, word 3 */
+#define X86_FEATURE_LAHF_LM       ( 3*32+ 0) /* LAHF/SAHF in long mode */
+#define X86_FEATURE_CMP_LEGACY    ( 3*32+ 1) /* If yes HyperThreading not valid */
+#define X86_FEATURE_SVM           ( 3*32+ 2) /* Secure virtual machine */
+#define X86_FEATURE_EXTAPIC       ( 3*32+ 3) /* Extended APIC space */
+#define X86_FEATURE_CR8_LEGACY    ( 3*32+ 4) /* CR8 in 32-bit mode */
+#define X86_FEATURE_ABM           ( 3*32+ 5) /* Advanced bit manipulation */
+#define X86_FEATURE_SSE4A         ( 3*32+ 6) /* SSE-4A */
+#define X86_FEATURE_MISALIGNSSE   ( 3*32+ 7) /* Misaligned SSE mode */
+#define X86_FEATURE_3DNOWPREFETCH ( 3*32+ 8) /* 3DNow prefetch instructions */
+#define X86_FEATURE_OSVW          ( 3*32+ 9) /* OS Visible Workaround */
+#define X86_FEATURE_IBS           ( 3*32+10) /* Instruction Based Sampling */
+#define X86_FEATURE_XOP           ( 3*32+11) /* extended AVX instructions */
+#define X86_FEATURE_SKINIT        ( 3*32+12) /* SKINIT/STGI instructions */
+#define X86_FEATURE_WDT           ( 3*32+13) /* Watchdog timer */
+#define X86_FEATURE_LWP           ( 3*32+15) /* Light Weight Profiling */
+#define X86_FEATURE_FMA4          ( 3*32+16) /* 4 operands MAC instructions */
+#define X86_FEATURE_NODEID_MSR    ( 3*32+19) /* NodeId MSR */
+#define X86_FEATURE_TBM           ( 3*32+21) /* trailing bit manipulations */
+#define X86_FEATURE_TOPOEXT       ( 3*32+22) /* topology extensions CPUID leafs */
+#define X86_FEATURE_DBEXT         ( 3*32+26) /* data breakpoint extension */
+#define X86_FEATURE_MWAITX        ( 3*32+29) /* MWAIT extension (MONITORX/MWAITX) */
+
+/* Intel-defined CPU features, CPUID level 0x0000000D:1.eax, word 4 */
+#define X86_FEATURE_XSAVEOPT      ( 4*32+ 0) /* XSAVEOPT instruction */
+#define X86_FEATURE_XSAVEC        ( 4*32+ 1) /* XSAVEC/XRSTORC instructions */
+#define X86_FEATURE_XGETBV1       ( 4*32+ 2) /* XGETBV with %ecx=1 */
+#define X86_FEATURE_XSAVES        ( 4*32+ 3) /* XSAVES/XRSTORS instructions */
+
+/* Intel-defined CPU features, CPUID level 0x00000007:0.ebx, word 5 */
+#define X86_FEATURE_FSGSBASE      ( 5*32+ 0) /* {RD,WR}{FS,GS}BASE instructions */
+#define X86_FEATURE_BMI1          ( 5*32+ 3) /* 1st bit manipulation extensions */
+#define X86_FEATURE_HLE           ( 5*32+ 4) /* Hardware Lock Elision */
+#define X86_FEATURE_AVX2          ( 5*32+ 5) /* AVX2 instructions */
+#define X86_FEATURE_SMEP          ( 5*32+ 7) /* Supervisor Mode Execution Protection */
+#define X86_FEATURE_BMI2          ( 5*32+ 8) /* 2nd bit manipulation extensions */
+#define X86_FEATURE_ERMS          ( 5*32+ 9) /* Enhanced REP MOVSB/STOSB */
+#define X86_FEATURE_INVPCID       ( 5*32+10) /* Invalidate Process Context ID */
+#define X86_FEATURE_RTM           ( 5*32+11) /* Restricted Transactional Memory */
+#define X86_FEATURE_CMT           ( 5*32+12) /* Cache Monitoring Technology */
+#define X86_FEATURE_NO_FPU_SEL    ( 5*32+13) /* FPU CS/DS stored as zero */
+#define X86_FEATURE_MPX           ( 5*32+14) /* Memory Protection Extensions */
+#define X86_FEATURE_CAT           ( 5*32+15) /* Cache Allocation Technology */
+#define X86_FEATURE_RDSEED        ( 5*32+18) /* RDSEED instruction */
+#define X86_FEATURE_ADX           ( 5*32+19) /* ADCX, ADOX instructions */
+#define X86_FEATURE_SMAP          ( 5*32+20) /* Supervisor Mode Access Prevention */
+
+#endif /* !__XEN_PUBLIC_ARCH_X86_FEATURESET_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 02/31] tools/libxc: Use public/featureset.h for cpuid policy generation
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
  2015-12-16 21:24 ` [PATCH RFC 01/31] xen/public: Export featureset information in the public API Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2015-12-22 16:29   ` Jan Beulich
  2015-12-16 21:24 ` [PATCH RFC 03/31] xen/x86: Store antifeatures inverted in a featureset Andrew Cooper
                   ` (28 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel
  Cc: Ian Jackson, Andrew Cooper, Tim Deegan, Ian Campbell, Jan Beulich

Rather than having a different local copy of some of the feature
definitions.

Modify the xc_cpuid_x86.c cpumask helpers to appropriate truncate the
new values, and add X86_FEATURE_TSC_ADJUST to the public API to allow
libxc to continue compiling.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Tim Deegan <tim@xen.org>
CC: Ian Campbell <Ian.Campbell@citrix.com>
CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
---
 tools/libxc/xc_cpufeature.h              | 145 -------------------------------
 tools/libxc/xc_cpuid_x86.c               |   8 +-
 xen/include/public/arch-x86/featureset.h |   1 +
 3 files changed, 5 insertions(+), 149 deletions(-)
 delete mode 100644 tools/libxc/xc_cpufeature.h

diff --git a/tools/libxc/xc_cpufeature.h b/tools/libxc/xc_cpufeature.h
deleted file mode 100644
index c3ddc80..0000000
--- a/tools/libxc/xc_cpufeature.h
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __LIBXC_CPUFEATURE_H
-#define __LIBXC_CPUFEATURE_H
-
-/* Intel-defined CPU features, CPUID level 0x00000001 (edx) */
-#define X86_FEATURE_FPU          0 /* Onboard FPU */
-#define X86_FEATURE_VME          1 /* Virtual Mode Extensions */
-#define X86_FEATURE_DE           2 /* Debugging Extensions */
-#define X86_FEATURE_PSE          3 /* Page Size Extensions */
-#define X86_FEATURE_TSC          4 /* Time Stamp Counter */
-#define X86_FEATURE_MSR          5 /* Model-Specific Registers, RDMSR, WRMSR */
-#define X86_FEATURE_PAE          6 /* Physical Address Extensions */
-#define X86_FEATURE_MCE          7 /* Machine Check Architecture */
-#define X86_FEATURE_CX8          8 /* CMPXCHG8 instruction */
-#define X86_FEATURE_APIC         9 /* Onboard APIC */
-#define X86_FEATURE_SEP         11 /* SYSENTER/SYSEXIT */
-#define X86_FEATURE_MTRR        12 /* Memory Type Range Registers */
-#define X86_FEATURE_PGE         13 /* Page Global Enable */
-#define X86_FEATURE_MCA         14 /* Machine Check Architecture */
-#define X86_FEATURE_CMOV        15 /* CMOV instruction */
-#define X86_FEATURE_PAT         16 /* Page Attribute Table */
-#define X86_FEATURE_PSE36       17 /* 36-bit PSEs */
-#define X86_FEATURE_PN          18 /* Processor serial number */
-#define X86_FEATURE_CLFLSH      19 /* Supports the CLFLUSH instruction */
-#define X86_FEATURE_DS          21 /* Debug Store */
-#define X86_FEATURE_ACPI        22 /* ACPI via MSR */
-#define X86_FEATURE_MMX         23 /* Multimedia Extensions */
-#define X86_FEATURE_FXSR        24 /* FXSAVE and FXRSTOR instructions */
-#define X86_FEATURE_XMM         25 /* Streaming SIMD Extensions */
-#define X86_FEATURE_XMM2        26 /* Streaming SIMD Extensions-2 */
-#define X86_FEATURE_SELFSNOOP   27 /* CPU self snoop */
-#define X86_FEATURE_HT          28 /* Hyper-Threading */
-#define X86_FEATURE_ACC         29 /* Automatic clock control */
-#define X86_FEATURE_IA64        30 /* IA-64 processor */
-#define X86_FEATURE_PBE         31 /* Pending Break Enable */
-
-/* AMD-defined CPU features, CPUID level 0x80000001 */
-/* Don't duplicate feature flags which are redundant with Intel! */
-#define X86_FEATURE_SYSCALL     11 /* SYSCALL/SYSRET */
-#define X86_FEATURE_MP          19 /* MP Capable. */
-#define X86_FEATURE_NX          20 /* Execute Disable */
-#define X86_FEATURE_MMXEXT      22 /* AMD MMX extensions */
-#define X86_FEATURE_FFXSR       25 /* FFXSR instruction optimizations */
-#define X86_FEATURE_PAGE1GB     26 /* 1Gb large page support */
-#define X86_FEATURE_RDTSCP      27 /* RDTSCP */
-#define X86_FEATURE_LM          29 /* Long Mode (x86-64) */
-#define X86_FEATURE_3DNOWEXT    30 /* AMD 3DNow! extensions */
-#define X86_FEATURE_3DNOW       31 /* 3DNow! */
-
-/* Intel-defined CPU features, CPUID level 0x00000001 (ecx) */
-#define X86_FEATURE_XMM3         0 /* Streaming SIMD Extensions-3 */
-#define X86_FEATURE_PCLMULQDQ    1 /* Carry-less multiplication */
-#define X86_FEATURE_DTES64       2 /* 64-bit Debug Store */
-#define X86_FEATURE_MWAIT        3 /* Monitor/Mwait support */
-#define X86_FEATURE_DSCPL        4 /* CPL Qualified Debug Store */
-#define X86_FEATURE_VMXE         5 /* Virtual Machine Extensions */
-#define X86_FEATURE_SMXE         6 /* Safer Mode Extensions */
-#define X86_FEATURE_EST          7 /* Enhanced SpeedStep */
-#define X86_FEATURE_TM2          8 /* Thermal Monitor 2 */
-#define X86_FEATURE_SSSE3        9 /* Supplemental Streaming SIMD Exts-3 */
-#define X86_FEATURE_CID         10 /* Context ID */
-#define X86_FEATURE_FMA         12 /* Fused Multiply Add */
-#define X86_FEATURE_CX16        13 /* CMPXCHG16B */
-#define X86_FEATURE_XTPR        14 /* Send Task Priority Messages */
-#define X86_FEATURE_PDCM        15 /* Perf/Debug Capability MSR */
-#define X86_FEATURE_PCID        17 /* Process Context ID */
-#define X86_FEATURE_DCA         18 /* Direct Cache Access */
-#define X86_FEATURE_SSE4_1      19 /* Streaming SIMD Extensions 4.1 */
-#define X86_FEATURE_SSE4_2      20 /* Streaming SIMD Extensions 4.2 */
-#define X86_FEATURE_X2APIC      21 /* x2APIC */
-#define X86_FEATURE_MOVBE       22 /* movbe instruction */
-#define X86_FEATURE_POPCNT      23 /* POPCNT instruction */
-#define X86_FEATURE_TSC_DEADLINE 24 /* "tdt" TSC Deadline Timer */
-#define X86_FEATURE_AES         25 /* AES acceleration instructions */
-#define X86_FEATURE_XSAVE       26 /* XSAVE/XRSTOR/XSETBV/XGETBV */
-#define X86_FEATURE_AVX         28 /* Advanced Vector Extensions */
-#define X86_FEATURE_F16C        29 /* Half-precision convert instruction */
-#define X86_FEATURE_RDRAND      30 /* Digital Random Number Generator */
-#define X86_FEATURE_HYPERVISOR  31 /* Running under some hypervisor */
-
-/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001 */
-#define X86_FEATURE_XSTORE       2 /* on-CPU RNG present (xstore insn) */
-#define X86_FEATURE_XSTORE_EN    3 /* on-CPU RNG enabled */
-#define X86_FEATURE_XCRYPT       6 /* on-CPU crypto (xcrypt insn) */
-#define X86_FEATURE_XCRYPT_EN    7 /* on-CPU crypto enabled */
-#define X86_FEATURE_ACE2         8 /* Advanced Cryptography Engine v2 */
-#define X86_FEATURE_ACE2_EN      9 /* ACE v2 enabled */
-#define X86_FEATURE_PHE         10 /* PadLock Hash Engine */
-#define X86_FEATURE_PHE_EN      11 /* PHE enabled */
-#define X86_FEATURE_PMM         12 /* PadLock Montgomery Multiplier */
-#define X86_FEATURE_PMM_EN      13 /* PMM enabled */
-
-/* More extended AMD flags: CPUID level 0x80000001, ecx */
-#define X86_FEATURE_LAHF_LM      0 /* LAHF/SAHF in long mode */
-#define X86_FEATURE_CMP_LEGACY   1 /* If yes HyperThreading not valid */
-#define X86_FEATURE_SVM          2 /* Secure virtual machine */
-#define X86_FEATURE_EXTAPIC      3 /* Extended APIC space */
-#define X86_FEATURE_CR8_LEGACY   4 /* CR8 in 32-bit mode */
-#define X86_FEATURE_ABM          5 /* Advanced bit manipulation */
-#define X86_FEATURE_SSE4A        6 /* SSE-4A */
-#define X86_FEATURE_MISALIGNSSE  7 /* Misaligned SSE mode */
-#define X86_FEATURE_3DNOWPREFETCH 8 /* 3DNow prefetch instructions */
-#define X86_FEATURE_OSVW         9 /* OS Visible Workaround */
-#define X86_FEATURE_IBS         10 /* Instruction Based Sampling */
-#define X86_FEATURE_XOP         11 /* extended AVX instructions */
-#define X86_FEATURE_SKINIT      12 /* SKINIT/STGI instructions */
-#define X86_FEATURE_WDT         13 /* Watchdog timer */
-#define X86_FEATURE_LWP         15 /* Light Weight Profiling */
-#define X86_FEATURE_FMA4        16 /* 4 operands MAC instructions */
-#define X86_FEATURE_NODEID_MSR  19 /* NodeId MSR */
-#define X86_FEATURE_TBM         21 /* trailing bit manipulations */
-#define X86_FEATURE_TOPOEXT     22 /* topology extensions CPUID leafs */
-#define X86_FEATURE_DBEXT       26 /* data breakpoint extension */
-
-/* Intel-defined CPU features, CPUID level 0x00000007:0 (ebx) */
-#define X86_FEATURE_FSGSBASE     0 /* {RD,WR}{FS,GS}BASE instructions */
-#define X86_FEATURE_TSC_ADJUST   1 /* Tsc thread offset */
-#define X86_FEATURE_BMI1         3 /* 1st group bit manipulation extensions */
-#define X86_FEATURE_HLE          4 /* Hardware Lock Elision */
-#define X86_FEATURE_AVX2         5 /* AVX2 instructions */
-#define X86_FEATURE_SMEP         7 /* Supervisor Mode Execution Protection */
-#define X86_FEATURE_BMI2         8 /* 2nd group bit manipulation extensions */
-#define X86_FEATURE_ERMS         9 /* Enhanced REP MOVSB/STOSB */
-#define X86_FEATURE_INVPCID     10 /* Invalidate Process Context ID */
-#define X86_FEATURE_RTM         11 /* Restricted Transactional Memory */
-#define X86_FEATURE_RDSEED      18 /* RDSEED instruction */
-#define X86_FEATURE_ADX         19 /* ADCX, ADOX instructions */
-#define X86_FEATURE_SMAP        20 /* Supervisor Mode Access Protection */
-
-
-#endif /* __LIBXC_CPUFEATURE_H */
diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
index 031c848..0a806cb 100644
--- a/tools/libxc/xc_cpuid_x86.c
+++ b/tools/libxc/xc_cpuid_x86.c
@@ -22,12 +22,12 @@
 #include <stdlib.h>
 #include <stdbool.h>
 #include "xc_private.h"
-#include "xc_cpufeature.h"
+#include <xen/arch-x86/featureset.h>
 #include <xen/hvm/params.h>
 
-#define bitmaskof(idx)      (1u << (idx))
-#define clear_bit(idx, dst) ((dst) &= ~(1u << (idx)))
-#define set_bit(idx, dst)   ((dst) |= (1u << (idx)))
+#define bitmaskof(idx)      (1u << ((idx) & 31))
+#define clear_bit(idx, dst) ((dst) &= ~bitmaskof(idx))
+#define set_bit(idx, dst)   ((dst) |=  bitmaskof(idx))
 
 #define DEF_MAX_BASE 0x0000000du
 #define DEF_MAX_INTELEXT  0x80000008u
diff --git a/xen/include/public/arch-x86/featureset.h b/xen/include/public/arch-x86/featureset.h
index 9a01d10..97e5c61 100644
--- a/xen/include/public/arch-x86/featureset.h
+++ b/xen/include/public/arch-x86/featureset.h
@@ -163,6 +163,7 @@
 
 /* Intel-defined CPU features, CPUID level 0x00000007:0.ebx, word 5 */
 #define X86_FEATURE_FSGSBASE      ( 5*32+ 0) /* {RD,WR}{FS,GS}BASE instructions */
+#define X86_FEATURE_TSC_ADJUST    ( 5*32+ 1) /* TSC_ADJUST MSR available */
 #define X86_FEATURE_BMI1          ( 5*32+ 3) /* 1st bit manipulation extensions */
 #define X86_FEATURE_HLE           ( 5*32+ 4) /* Hardware Lock Elision */
 #define X86_FEATURE_AVX2          ( 5*32+ 5) /* AVX2 instructions */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 03/31] xen/x86: Store antifeatures inverted in a featureset
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
  2015-12-16 21:24 ` [PATCH RFC 01/31] xen/public: Export featureset information in the public API Andrew Cooper
  2015-12-16 21:24 ` [PATCH RFC 02/31] tools/libxc: Use public/featureset.h for cpuid policy generation Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2015-12-22 16:32   ` Jan Beulich
  2015-12-16 21:24 ` [PATCH RFC 04/31] xen/x86: Mask out unknown features from Xen's capabilities Andrew Cooper
                   ` (27 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Jan Beulich

Awkwardly, some new feature bits mean "Feature $X no longer works".
Store these inverted in a featureset.

This permits safe zero-extending of a smaller featureset as part of a
comparison, and safe reasoning (subset?, superset?, compatible? etc.)
without specific knowldge of meaning of each bit.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
---
 xen/arch/x86/Makefile                    |  1 +
 xen/arch/x86/cpu/common.c                |  3 +++
 xen/arch/x86/cpu/cpu.h                   |  2 ++
 xen/arch/x86/cpuid/Makefile              |  1 +
 xen/arch/x86/cpuid/cpuid-private.h       | 27 +++++++++++++++++++++++++++
 xen/arch/x86/cpuid/cpuid.c               | 16 ++++++++++++++++
 xen/include/asm-x86/cpufeature.h         |  2 +-
 xen/include/public/arch-x86/featureset.h |  7 ++++++-
 8 files changed, 57 insertions(+), 2 deletions(-)
 create mode 100644 xen/arch/x86/cpuid/Makefile
 create mode 100644 xen/arch/x86/cpuid/cpuid-private.h
 create mode 100644 xen/arch/x86/cpuid/cpuid.c

diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index 5f24951..122cbe9 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -1,5 +1,6 @@
 subdir-y += acpi
 subdir-y += cpu
+subdir-y += cpuid
 subdir-y += genapic
 subdir-y += hvm
 subdir-y += mm
diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c
index 87bd912..3496b13 100644
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -323,6 +323,9 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
 	 * The vendor-specific functions might have changed features.  Now
 	 * we do "generic changes."
 	 */
+	for (i = 0; i < XEN_NR_FEATURESET_ENTRIES; ++i) {
+		c->x86_capability[i] ^= inverted_features[i];
+	}
 
 	for (i = 0 ; i < NCAPINTS ; ++i)
 		c->x86_capability[i] &= ~cleared_caps[i];
diff --git a/xen/arch/x86/cpu/cpu.h b/xen/arch/x86/cpu/cpu.h
index 1877e7d..ca4048b 100644
--- a/xen/arch/x86/cpu/cpu.h
+++ b/xen/arch/x86/cpu/cpu.h
@@ -1,3 +1,5 @@
+#include "../cpuid/cpuid-private.h"
+
 /* attempt to consolidate cpu attributes */
 struct cpu_dev {
 	char	* c_vendor;
diff --git a/xen/arch/x86/cpuid/Makefile b/xen/arch/x86/cpuid/Makefile
new file mode 100644
index 0000000..3fb2e0b
--- /dev/null
+++ b/xen/arch/x86/cpuid/Makefile
@@ -0,0 +1 @@
+obj-y += cpuid.o
diff --git a/xen/arch/x86/cpuid/cpuid-private.h b/xen/arch/x86/cpuid/cpuid-private.h
new file mode 100644
index 0000000..c8b47b3
--- /dev/null
+++ b/xen/arch/x86/cpuid/cpuid-private.h
@@ -0,0 +1,27 @@
+#ifdef __XEN__
+
+#include <asm/cpufeature.h>
+
+#include <xen/lib.h>
+
+#else
+
+# error TODO for userspace
+
+#endif
+
+/*
+ * Bitmap of "anti" features which have their representation inverted when
+ * stored as a featureset.
+ */
+extern const uint32_t inverted_features[XEN_NR_FEATURESET_ENTRIES];
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/x86/cpuid/cpuid.c b/xen/arch/x86/cpuid/cpuid.c
new file mode 100644
index 0000000..1578725
--- /dev/null
+++ b/xen/arch/x86/cpuid/cpuid.c
@@ -0,0 +1,16 @@
+#include "cpuid-private.h"
+
+const uint32_t inverted_features[XEN_NR_FEATURESET_ENTRIES] =
+{
+    [cpufeat_word(X86_FEATURE_FPU_SEL)] = cpufeat_mask(X86_FEATURE_FPU_SEL),
+};
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/asm-x86/cpufeature.h b/xen/include/asm-x86/cpufeature.h
index 87724a0..547ed7d 100644
--- a/xen/include/asm-x86/cpufeature.h
+++ b/xen/include/asm-x86/cpufeature.h
@@ -81,7 +81,7 @@
 
 #define cpu_has_smep            boot_cpu_has(X86_FEATURE_SMEP)
 #define cpu_has_smap            boot_cpu_has(X86_FEATURE_SMAP)
-#define cpu_has_fpu_sel         (!boot_cpu_has(X86_FEATURE_NO_FPU_SEL))
+#define cpu_has_fpu_sel         boot_cpu_has(X86_FEATURE_FPU_SEL)
 
 #define cpu_has_ffxsr           ((boot_cpu_data.x86_vendor == X86_VENDOR_AMD) \
                                  && boot_cpu_has(X86_FEATURE_FFXSR))
diff --git a/xen/include/public/arch-x86/featureset.h b/xen/include/public/arch-x86/featureset.h
index 97e5c61..19abb98 100644
--- a/xen/include/public/arch-x86/featureset.h
+++ b/xen/include/public/arch-x86/featureset.h
@@ -35,6 +35,11 @@
  * contain any synthesied values.  New words may be added to the end of
  * featureset.
  *
+ * "Anti" features have their representation inverted.  This permits safe
+ * zero-extending of a smaller featureset as part of a comparison, and safe
+ * reasoning (subset?, superset?, compatible? etc.) without specific knowldge
+ * of meaning of each bit.
+ *
  * All featureset words currently originate from leaves specified for the
  * CPUID instruction, but this is not preclude other sources of information.
  */
@@ -173,7 +178,7 @@
 #define X86_FEATURE_INVPCID       ( 5*32+10) /* Invalidate Process Context ID */
 #define X86_FEATURE_RTM           ( 5*32+11) /* Restricted Transactional Memory */
 #define X86_FEATURE_CMT           ( 5*32+12) /* Cache Monitoring Technology */
-#define X86_FEATURE_NO_FPU_SEL    ( 5*32+13) /* FPU CS/DS stored as zero */
+#define X86_FEATURE_FPU_SEL       ( 5*32+13) /* ! FPU CS/DS stored as zero */
 #define X86_FEATURE_MPX           ( 5*32+14) /* Memory Protection Extensions */
 #define X86_FEATURE_CAT           ( 5*32+15) /* Cache Allocation Technology */
 #define X86_FEATURE_RDSEED        ( 5*32+18) /* RDSEED instruction */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 04/31] xen/x86: Mask out unknown features from Xen's capabilities
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (2 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 03/31] xen/x86: Store antifeatures inverted in a featureset Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2015-12-22 16:42   ` Jan Beulich
  2015-12-16 21:24 ` [PATCH RFC 05/31] xen/x86: Collect more CPUID feature words Andrew Cooper
                   ` (26 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Jan Beulich

If Xen doesn't know about a feature, it is unsafe for use and should be
deliberately hidden from Xen's capabilities.

This doesn't make a practical difference yet, but will make a difference
later when the guest featuresets are seeded from the host featureset.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
---
 xen/arch/x86/cpu/common.c          |   1 +
 xen/arch/x86/cpuid/cpuid-private.h |  26 +++++++++
 xen/arch/x86/cpuid/cpuid.c         | 105 +++++++++++++++++++++++++++++++++++++
 3 files changed, 132 insertions(+)

diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c
index 3496b13..5bdb4b3 100644
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -324,6 +324,7 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
 	 * we do "generic changes."
 	 */
 	for (i = 0; i < XEN_NR_FEATURESET_ENTRIES; ++i) {
+		c->x86_capability[i] &= known_features[i];
 		c->x86_capability[i] ^= inverted_features[i];
 	}
 
diff --git a/xen/arch/x86/cpuid/cpuid-private.h b/xen/arch/x86/cpuid/cpuid-private.h
index c8b47b3..a4d582c 100644
--- a/xen/arch/x86/cpuid/cpuid-private.h
+++ b/xen/arch/x86/cpuid/cpuid-private.h
@@ -10,6 +10,32 @@
 
 #endif
 
+/* Mask of bits which are shared between 1d and e1d. */
+#define SHARED_1d                               \
+    (cpufeat_mask(X86_FEATURE_FPU)   |          \
+     cpufeat_mask(X86_FEATURE_VME)   |          \
+     cpufeat_mask(X86_FEATURE_DE)    |          \
+     cpufeat_mask(X86_FEATURE_PSE)   |          \
+     cpufeat_mask(X86_FEATURE_TSC)   |          \
+     cpufeat_mask(X86_FEATURE_MSR)   |          \
+     cpufeat_mask(X86_FEATURE_PAE)   |          \
+     cpufeat_mask(X86_FEATURE_MCE)   |          \
+     cpufeat_mask(X86_FEATURE_CX8)   |          \
+     cpufeat_mask(X86_FEATURE_APIC)  |          \
+     cpufeat_mask(X86_FEATURE_MTRR)  |          \
+     cpufeat_mask(X86_FEATURE_PGE)   |          \
+     cpufeat_mask(X86_FEATURE_MCA)   |          \
+     cpufeat_mask(X86_FEATURE_CMOV)  |          \
+     cpufeat_mask(X86_FEATURE_PAT)   |          \
+     cpufeat_mask(X86_FEATURE_PSE36) |          \
+     cpufeat_mask(X86_FEATURE_MMX)   |          \
+     cpufeat_mask(X86_FEATURE_FXSR))
+
+/*
+ * Bitmap of features known to Xen.
+ */
+extern const uint32_t known_features[XEN_NR_FEATURESET_ENTRIES];
+
 /*
  * Bitmap of "anti" features which have their representation inverted when
  * stored as a featureset.
diff --git a/xen/arch/x86/cpuid/cpuid.c b/xen/arch/x86/cpuid/cpuid.c
index 1578725..6ee9ce2 100644
--- a/xen/arch/x86/cpuid/cpuid.c
+++ b/xen/arch/x86/cpuid/cpuid.c
@@ -1,5 +1,110 @@
 #include "cpuid-private.h"
 
+const uint32_t known_features[XEN_NR_FEATURESET_ENTRIES] =
+{
+    [cpufeat_word(X86_FEATURE_FPU)] = (SHARED_1d                           |
+                                       cpufeat_mask(X86_FEATURE_SEP)       |
+                                       cpufeat_mask(X86_FEATURE_PN)        |
+                                       cpufeat_mask(X86_FEATURE_CLFLSH)    |
+                                       cpufeat_mask(X86_FEATURE_DS)        |
+                                       cpufeat_mask(X86_FEATURE_ACPI)      |
+                                       cpufeat_mask(X86_FEATURE_XMM)       |
+                                       cpufeat_mask(X86_FEATURE_XMM2)      |
+                                       cpufeat_mask(X86_FEATURE_SELFSNOOP) |
+                                       cpufeat_mask(X86_FEATURE_HT)        |
+                                       cpufeat_mask(X86_FEATURE_ACC)       |
+                                       cpufeat_mask(X86_FEATURE_IA64)      |
+                                       cpufeat_mask(X86_FEATURE_PBE)),
+
+    [cpufeat_word(X86_FEATURE_XMM3)] = (cpufeat_mask(X86_FEATURE_XMM3)         |
+                                        cpufeat_mask(X86_FEATURE_PCLMULQDQ)    |
+                                        cpufeat_mask(X86_FEATURE_DTES64)       |
+                                        cpufeat_mask(X86_FEATURE_MWAIT)        |
+                                        cpufeat_mask(X86_FEATURE_DSCPL)        |
+                                        cpufeat_mask(X86_FEATURE_VMXE)         |
+                                        cpufeat_mask(X86_FEATURE_SMXE)         |
+                                        cpufeat_mask(X86_FEATURE_EST)          |
+                                        cpufeat_mask(X86_FEATURE_TM2)          |
+                                        cpufeat_mask(X86_FEATURE_SSSE3)        |
+                                        cpufeat_mask(X86_FEATURE_CID)          |
+                                        cpufeat_mask(X86_FEATURE_FMA)          |
+                                        cpufeat_mask(X86_FEATURE_CX16)         |
+                                        cpufeat_mask(X86_FEATURE_XTPR)         |
+                                        cpufeat_mask(X86_FEATURE_PDCM)         |
+                                        cpufeat_mask(X86_FEATURE_PCID)         |
+                                        cpufeat_mask(X86_FEATURE_DCA)          |
+                                        cpufeat_mask(X86_FEATURE_SSE4_1)       |
+                                        cpufeat_mask(X86_FEATURE_SSE4_2)       |
+                                        cpufeat_mask(X86_FEATURE_X2APIC)       |
+                                        cpufeat_mask(X86_FEATURE_MOVBE)        |
+                                        cpufeat_mask(X86_FEATURE_POPCNT)       |
+                                        cpufeat_mask(X86_FEATURE_TSC_DEADLINE) |
+                                        cpufeat_mask(X86_FEATURE_AES)          |
+                                        cpufeat_mask(X86_FEATURE_XSAVE)        |
+                                        cpufeat_mask(X86_FEATURE_OSXSAVE)      |
+                                        cpufeat_mask(X86_FEATURE_AVX)          |
+                                        cpufeat_mask(X86_FEATURE_F16C)         |
+                                        cpufeat_mask(X86_FEATURE_RDRAND)       |
+                                        cpufeat_mask(X86_FEATURE_HYPERVISOR)),
+
+    [cpufeat_word(X86_FEATURE_SYSCALL)] = (SHARED_1d                          |
+                                           cpufeat_mask(X86_FEATURE_SYSCALL)  |
+                                           cpufeat_mask(X86_FEATURE_MP)       |
+                                           cpufeat_mask(X86_FEATURE_NX)       |
+                                           cpufeat_mask(X86_FEATURE_MMXEXT)   |
+                                           cpufeat_mask(X86_FEATURE_FFXSR)    |
+                                           cpufeat_mask(X86_FEATURE_PAGE1GB)  |
+                                           cpufeat_mask(X86_FEATURE_RDTSCP)   |
+                                           cpufeat_mask(X86_FEATURE_LM)       |
+                                           cpufeat_mask(X86_FEATURE_3DNOWEXT) |
+                                           cpufeat_mask(X86_FEATURE_3DNOW)),
+
+    [cpufeat_word(X86_FEATURE_LAHF_LM)] = (cpufeat_mask(X86_FEATURE_LAHF_LM)       |
+                                           cpufeat_mask(X86_FEATURE_CMP_LEGACY)    |
+                                           cpufeat_mask(X86_FEATURE_SVM)           |
+                                           cpufeat_mask(X86_FEATURE_EXTAPIC)       |
+                                           cpufeat_mask(X86_FEATURE_CR8_LEGACY)    |
+                                           cpufeat_mask(X86_FEATURE_ABM)           |
+                                           cpufeat_mask(X86_FEATURE_SSE4A)         |
+                                           cpufeat_mask(X86_FEATURE_MISALIGNSSE)   |
+                                           cpufeat_mask(X86_FEATURE_3DNOWPREFETCH) |
+                                           cpufeat_mask(X86_FEATURE_OSVW)          |
+                                           cpufeat_mask(X86_FEATURE_IBS)           |
+                                           cpufeat_mask(X86_FEATURE_XOP)           |
+                                           cpufeat_mask(X86_FEATURE_SKINIT)        |
+                                           cpufeat_mask(X86_FEATURE_WDT)           |
+                                           cpufeat_mask(X86_FEATURE_LWP)           |
+                                           cpufeat_mask(X86_FEATURE_FMA4)          |
+                                           cpufeat_mask(X86_FEATURE_NODEID_MSR)    |
+                                           cpufeat_mask(X86_FEATURE_TBM)           |
+                                           cpufeat_mask(X86_FEATURE_TOPOEXT)       |
+                                           cpufeat_mask(X86_FEATURE_DBEXT)         |
+                                           cpufeat_mask(X86_FEATURE_MWAITX)),
+
+    [cpufeat_word(X86_FEATURE_XSAVEOPT)] = (cpufeat_mask(X86_FEATURE_XSAVEOPT) |
+                                            cpufeat_mask(X86_FEATURE_XSAVEC)   |
+                                            cpufeat_mask(X86_FEATURE_XGETBV1)  |
+                                            cpufeat_mask(X86_FEATURE_XSAVES)),
+
+    [cpufeat_word(X86_FEATURE_FSGSBASE)] = (cpufeat_mask(X86_FEATURE_FSGSBASE)   |
+                                            cpufeat_mask(X86_FEATURE_TSC_ADJUST) |
+                                            cpufeat_mask(X86_FEATURE_BMI1)       |
+                                            cpufeat_mask(X86_FEATURE_HLE)        |
+                                            cpufeat_mask(X86_FEATURE_AVX2)       |
+                                            cpufeat_mask(X86_FEATURE_SMEP)       |
+                                            cpufeat_mask(X86_FEATURE_BMI2)       |
+                                            cpufeat_mask(X86_FEATURE_ERMS)       |
+                                            cpufeat_mask(X86_FEATURE_INVPCID)    |
+                                            cpufeat_mask(X86_FEATURE_RTM)        |
+                                            cpufeat_mask(X86_FEATURE_CMT)        |
+                                            cpufeat_mask(X86_FEATURE_FPU_SEL)    |
+                                            cpufeat_mask(X86_FEATURE_MPX)        |
+                                            cpufeat_mask(X86_FEATURE_CAT)        |
+                                            cpufeat_mask(X86_FEATURE_RDSEED)     |
+                                            cpufeat_mask(X86_FEATURE_ADX)        |
+                                            cpufeat_mask(X86_FEATURE_SMAP)),
+};
+
 const uint32_t inverted_features[XEN_NR_FEATURESET_ENTRIES] =
 {
     [cpufeat_word(X86_FEATURE_FPU_SEL)] = cpufeat_mask(X86_FEATURE_FPU_SEL),
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 05/31] xen/x86: Collect more CPUID feature words
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (3 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 04/31] xen/x86: Mask out unknown features from Xen's capabilities Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2015-12-22 16:46   ` Jan Beulich
  2015-12-16 21:24 ` [PATCH RFC 06/31] xen/x86: Infrastructure to calculate guest featuresets Andrew Cooper
                   ` (25 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Jan Beulich

New words are:
 * 0x00000007:0.ecx - New for Intel Skylake processors
 * 0x80000007.edx - Contains Invarient TSC
 * 0x80000008.ebx - Newly used for AMD Zen processors

In addition, replace a lot of open-coded Invarient TSC manipulation.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
---
 xen/arch/x86/cpu/amd.c                   |  2 +-
 xen/arch/x86/cpu/common.c                |  9 ++++++++-
 xen/arch/x86/cpu/intel.c                 |  2 +-
 xen/arch/x86/cpuid/cpuid.c               |  6 ++++++
 xen/arch/x86/domain.c                    |  2 +-
 xen/include/public/arch-x86/featureset.h | 14 +++++++++++++-
 6 files changed, 30 insertions(+), 5 deletions(-)

diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c
index cde655f..5d22863 100644
--- a/xen/arch/x86/cpu/amd.c
+++ b/xen/arch/x86/cpu/amd.c
@@ -481,7 +481,7 @@ static void __devinit init_amd(struct cpuinfo_x86 *c)
 
 	if (c->extended_cpuid_level >= 0x80000007) {
 		c->x86_power = cpuid_edx(0x80000007);
-		if (c->x86_power & (1<<8)) {
+		if (c->x86_power & cpufeat_mask(X86_FEATURE_ITSC)) {
 			set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability);
 			set_bit(X86_FEATURE_NONSTOP_TSC, c->x86_capability);
 			if (c->x86 != 0x11)
diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c
index 5bdb4b3..b48ce58 100644
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -260,13 +260,20 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 *c)
 
 		if ( c->extended_cpuid_level >= 0x80000004 )
 			get_model_name(c); /* Default name */
+		if ( c->extended_cpuid_level >= 0x80000007 )
+			c->x86_capability[cpufeat_word(X86_FEATURE_ITSC)]
+				= cpuid_edx(0x80000007);
+		if ( c->extended_cpuid_level >= 0x80000008 )
+			c->x86_capability[cpufeat_word(X86_FEATURE_CLZERO)]
+				= cpuid_ebx(0x80000008);
 	}
 
 	/* Intel-defined flags: level 0x00000007 */
 	if ( c->cpuid_level >= 0x00000007 )
 		cpuid_count(0x00000007, 0, &tmp,
 			    &c->x86_capability[cpufeat_word(X86_FEATURE_FSGSBASE)],
-			    &tmp, &tmp);
+			    &c->x86_capability[cpufeat_word(X86_FEATURE_PREFETCHWT1)],
+			    &tmp);
 }
 
 /*
diff --git a/xen/arch/x86/cpu/intel.c b/xen/arch/x86/cpu/intel.c
index bf6f90d..bd595a5 100644
--- a/xen/arch/x86/cpu/intel.c
+++ b/xen/arch/x86/cpu/intel.c
@@ -273,7 +273,7 @@ static void __devinit init_intel(struct cpuinfo_x86 *c)
 	if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
 		(c->x86 == 0x6 && c->x86_model >= 0x0e))
 		set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability);
-	if (cpuid_edx(0x80000007) & (1u<<8)) {
+	if (cpu_has(c, X86_FEATURE_ITSC)) {
 		set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability);
 		set_bit(X86_FEATURE_NONSTOP_TSC, c->x86_capability);
 		set_bit(X86_FEATURE_TSC_RELIABLE, c->x86_capability);
diff --git a/xen/arch/x86/cpuid/cpuid.c b/xen/arch/x86/cpuid/cpuid.c
index 6ee9ce2..56993d2 100644
--- a/xen/arch/x86/cpuid/cpuid.c
+++ b/xen/arch/x86/cpuid/cpuid.c
@@ -103,6 +103,12 @@ const uint32_t known_features[XEN_NR_FEATURESET_ENTRIES] =
                                             cpufeat_mask(X86_FEATURE_RDSEED)     |
                                             cpufeat_mask(X86_FEATURE_ADX)        |
                                             cpufeat_mask(X86_FEATURE_SMAP)),
+
+    [cpufeat_word(X86_FEATURE_PREFETCHWT1)] = (cpufeat_mask(X86_FEATURE_PREFETCHWT1)),
+
+    [cpufeat_word(X86_FEATURE_ITSC)] = (cpufeat_mask(X86_FEATURE_ITSC)),
+
+    [cpufeat_word(X86_FEATURE_CLZERO)] = (cpufeat_mask(X86_FEATURE_CLZERO)),
 };
 
 const uint32_t inverted_features[XEN_NR_FEATURESET_ENTRIES] =
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index a877bab..51adb8d 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -2165,7 +2165,7 @@ void domain_cpuid(
              */
             if ( (input == 0x80000007) && /* Advanced Power Management */
                  !d->disable_migrate && !d->arch.vtsc )
-                *edx &= ~(1u<<8); /* TSC Invariant */
+                *edx &= ~cpufeat_mask(X86_FEATURE_ITSC);
 
             return;
         }
diff --git a/xen/include/public/arch-x86/featureset.h b/xen/include/public/arch-x86/featureset.h
index 19abb98..f48ad5b 100644
--- a/xen/include/public/arch-x86/featureset.h
+++ b/xen/include/public/arch-x86/featureset.h
@@ -57,7 +57,10 @@
 #define XEN_FEATURESET_e1c    3 /* 0x80000001.ecx      */
 #define XEN_FEATURESET_Da1    4 /* 0x0000000d:1.eax    */
 #define XEN_FEATURESET_7b0    5 /* 0x00000007:0.ebx    */
-#define XEN_NR_FEATURESET_ENTRIES (XEN_FEATURESET_7b0 + 1)
+#define XEN_FEATURESET_7c0    6 /* 0x00000007:0.ecx    */
+#define XEN_FEATURESET_e7d    7 /* 0x80000007.edx      */
+#define XEN_FEATURESET_e8b    8 /* 0x80000008.ebx      */
+#define XEN_NR_FEATURESET_ENTRIES (XEN_FEATURESET_e8b + 1)
 
 
 /* Intel-defined CPU features, CPUID level 0x00000001.edx, word 0 */
@@ -185,6 +188,15 @@
 #define X86_FEATURE_ADX           ( 5*32+19) /* ADCX, ADOX instructions */
 #define X86_FEATURE_SMAP          ( 5*32+20) /* Supervisor Mode Access Prevention */
 
+/* Intel-defined CPU features, CPUID level 0x00000007:0.ecx, word 6 */
+#define X86_FEATURE_PREFETCHWT1   ( 6*32+ 0) /* PREFETCHWT1 instruction */
+
+/* AMD-defined CPU features, CPUID level 0x80000007.edx, word 7 */
+#define X86_FEATURE_ITSC          ( 7*32+ 8) /* Invariant TSC */
+
+/* AMD-defined CPU features, CPUID level 0x80000008.ebx, word 8 */
+#define X86_FEATURE_CLZERO        ( 8*32+ 0) /* CLZERO instruction */
+
 #endif /* !__XEN_PUBLIC_ARCH_X86_FEATURESET_H__ */
 
 /*
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 06/31] xen/x86: Infrastructure to calculate guest featuresets
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (4 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 05/31] xen/x86: Collect more CPUID feature words Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2015-12-22 16:50   ` Jan Beulich
  2015-12-16 21:24 ` [PATCH RFC 07/31] xen/x86: Export host featureset via SYSCTL Andrew Cooper
                   ` (24 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Jan Beulich

Guest featuresets are seeded from the host featureset, and the host featureset
has calculated in the front of boot_cpu_data.x86_capability.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
---
 xen/arch/x86/Makefile       |  1 +
 xen/arch/x86/cpuid.c        | 23 +++++++++++++++++++++++
 xen/arch/x86/setup.c        |  3 +++
 xen/include/asm-x86/cpuid.h | 22 ++++++++++++++++++++++
 4 files changed, 49 insertions(+)
 create mode 100644 xen/arch/x86/cpuid.c
 create mode 100644 xen/include/asm-x86/cpuid.h

diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index 122cbe9..c1f6f73 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -15,6 +15,7 @@ obj-bin-y += bzimage.init.o
 obj-bin-y += clear_page.o
 obj-bin-y += copy_page.o
 obj-y += compat.o
+obj-y += cpuid.o
 obj-y += debug.o
 obj-y += delay.o
 obj-bin-y += dmi_scan.init.o
diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c
new file mode 100644
index 0000000..099e145
--- /dev/null
+++ b/xen/arch/x86/cpuid.c
@@ -0,0 +1,23 @@
+#include <xen/lib.h>
+#include <xen/init.h>
+#include <asm/processor.h>
+#include <asm/cpuid.h>
+
+uint32_t __read_mostly host_featureset[XEN_NR_FEATURESET_ENTRIES];
+
+void __init calculate_featuresets(void)
+{
+    /* Host featureset. */
+    memcpy(host_featureset, boot_cpu_data.x86_capability,
+           sizeof(host_featureset));
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 54995ed..d91c2fb 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -50,6 +50,7 @@
 #include <asm/nmi.h>
 #include <asm/alternative.h>
 #include <asm/mc146818rtc.h>
+#include <asm/cpuid.h>
 
 /* opt_nosmp: If true, secondary processors are ignored. */
 static bool_t __initdata opt_nosmp;
@@ -1434,6 +1435,8 @@ void __init noreturn __start_xen(unsigned long mbi_p)
                "Multiple initrd candidates, picking module #%u\n",
                initrdidx);
 
+    calculate_featuresets();
+
     /*
      * Temporarily clear SMAP in CR4 to allow user-accesses in construct_dom0().
      * This saves a large number of corner cases interactions with
diff --git a/xen/include/asm-x86/cpuid.h b/xen/include/asm-x86/cpuid.h
new file mode 100644
index 0000000..c303c74
--- /dev/null
+++ b/xen/include/asm-x86/cpuid.h
@@ -0,0 +1,22 @@
+#ifndef __X86_CPUID_H__
+#define __X86_CPUID_H__
+
+#include <xen/types.h>
+#include <asm/cpufeature.h>
+#include <public/sysctl.h>
+
+extern uint32_t host_featureset[XEN_NR_FEATURESET_ENTRIES];
+
+void calculate_featuresets(void);
+
+#endif /* !__X86_CPUID_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 07/31] xen/x86: Export host featureset via SYSCTL
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (5 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 06/31] xen/x86: Infrastructure to calculate guest featuresets Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2015-12-22 16:57   ` Jan Beulich
  2015-12-16 21:24 ` [PATCH RFC 08/31] tools/stubs: Expose host featureset to userspace Andrew Cooper
                   ` (23 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Tim Deegan, Ian Campbell, Jan Beulich

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Tim Deegan <tim@xen.org>
CC: Ian Campbell <Ian.Campbell@citrix.com>
---
 xen/arch/x86/sysctl.c       | 51 +++++++++++++++++++++++++++++++++++++++++++++
 xen/include/public/sysctl.h | 20 ++++++++++++++++++
 2 files changed, 71 insertions(+)

diff --git a/xen/arch/x86/sysctl.c b/xen/arch/x86/sysctl.c
index 38b5dcb..1f483b8 100644
--- a/xen/arch/x86/sysctl.c
+++ b/xen/arch/x86/sysctl.c
@@ -29,6 +29,7 @@
 #include <xen/cpu.h>
 #include <xsm/xsm.h>
 #include <asm/psr.h>
+#include <asm/cpuid.h>
 
 #define get_xen_guest_handle(val, hnd)  do { val = (hnd).p; } while (0)
 
@@ -190,6 +191,56 @@ long arch_do_sysctl(
         }
         break;
 
+    case XEN_SYSCTL_get_featureset:
+    {
+        uint32_t *featureset;
+        unsigned int nr;
+
+        /* Request for maximum number of features? */
+        if ( guest_handle_is_null(sysctl->u.featureset.features) )
+        {
+            sysctl->u.featureset.nr_features = XEN_NR_FEATURESET_ENTRIES;
+            if ( __copy_to_guest(u_sysctl, sysctl, 1) )
+                ret = -EFAULT;
+            break;
+        }
+
+        /* Clip the number of entries. */
+        nr = min_t(unsigned int, sysctl->u.featureset.nr_features,
+                   XEN_NR_FEATURESET_ENTRIES);
+
+        switch ( sysctl->u.featureset.index )
+        {
+        case XEN_SYSCTL_featureset_host:
+            featureset = host_featureset;
+            break;
+
+        default:
+            featureset = NULL;
+            break;
+        }
+
+        /* Bad featureset index? */
+        if ( !ret && !featureset )
+            ret = -EINVAL;
+
+        /* Copy the requested featureset into place. */
+        if ( !ret && copy_to_guest(sysctl->u.featureset.features,
+                                   featureset, nr) )
+            ret = -EFAULT;
+
+        /* Inform the caller of how many features we wrote. */
+        sysctl->u.featureset.nr_features = nr;
+        if ( !ret && __copy_to_guest(u_sysctl, sysctl, 1) )
+            ret = -EFAULT;
+
+        /* Inform the caller if there was more data to provide. */
+        if ( !ret && nr < XEN_NR_FEATURESET_ENTRIES )
+            ret = -ENOBUFS;
+
+        break;
+    }
+
     default:
         ret = -ENOSYS;
         break;
diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
index 0cacacc..dfde433 100644
--- a/xen/include/public/sysctl.h
+++ b/xen/include/public/sysctl.h
@@ -764,6 +764,24 @@ struct xen_sysctl_tmem_op {
 typedef struct xen_sysctl_tmem_op xen_sysctl_tmem_op_t;
 DEFINE_XEN_GUEST_HANDLE(xen_sysctl_tmem_op_t);
 
+/*
+ * XEN_SYSCTL_get_featureset (x86 specific)
+ *
+ * Return information about the maximum sets of features which can be offered
+ * to different types of guests.  This is all strictly information as found in
+ * `cpuid` feature leaves with no synthetic alterations.
+ */
+struct xen_sysctl_featureset {
+#define XEN_SYSCTL_featureset_host      0
+    uint32_t index;       /* IN: Which featureset to query? */
+    uint32_t nr_features; /* IN/OUT: Number of entries in/written to
+                           * 'features', or the maximum number of features if
+                           * the guest handle is NULL. */
+    XEN_GUEST_HANDLE_64(uint32) features; /* OUT: */
+};
+typedef struct xen_sysctl_featureset xen_sysctl_featureset_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_featureset_t);
+
 struct xen_sysctl {
     uint32_t cmd;
 #define XEN_SYSCTL_readconsole                    1
@@ -789,6 +807,7 @@ struct xen_sysctl {
 #define XEN_SYSCTL_pcitopoinfo                   22
 #define XEN_SYSCTL_psr_cat_op                    23
 #define XEN_SYSCTL_tmem_op                       24
+#define XEN_SYSCTL_get_featureset                25
     uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */
     union {
         struct xen_sysctl_readconsole       readconsole;
@@ -814,6 +833,7 @@ struct xen_sysctl {
         struct xen_sysctl_psr_cmt_op        psr_cmt_op;
         struct xen_sysctl_psr_cat_op        psr_cat_op;
         struct xen_sysctl_tmem_op           tmem_op;
+        struct xen_sysctl_featureset        featureset;
         uint8_t                             pad[128];
     } u;
 };
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 08/31] tools/stubs: Expose host featureset to userspace
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (6 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 07/31] xen/x86: Export host featureset via SYSCTL Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2016-01-05 15:36   ` Ian Campbell
  2015-12-16 21:24 ` [PATCH RFC 09/31] xen/x86: Calculate PV featureset Andrew Cooper
                   ` (22 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel
  Cc: Wei Liu, Ian Campbell, Andrew Cooper, Ian Jackson, Rob Hoes, David Scott

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Ian Campbell <Ian.Campbell@citrix.com>
CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
CC: Wei Liu <wei.liu2@citrix.com>
CC: David Scott <dave@recoil.org>
CC: Rob Hoes <Rob.Hoes@citrix.com>
---
 tools/libxc/include/xenctrl.h       |  3 +++
 tools/libxc/xc_misc.c               | 27 +++++++++++++++++++++++++++
 tools/ocaml/libs/xc/xenctrl.ml      |  3 +++
 tools/ocaml/libs/xc/xenctrl.mli     |  4 ++++
 tools/ocaml/libs/xc/xenctrl_stubs.c | 35 +++++++++++++++++++++++++++++++++++
 5 files changed, 72 insertions(+)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 37205c2..27e1f45 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -2839,6 +2839,9 @@ int xc_psr_cat_get_domain_data(xc_interface *xch, uint32_t domid,
                                uint64_t *data);
 int xc_psr_cat_get_l3_info(xc_interface *xch, uint32_t socket,
                            uint32_t *cos_max, uint32_t *cbm_len);
+
+int xc_get_featureset(xc_interface *xch, uint32_t index,
+                      uint32_t *nr_features, uint32_t *featureset);
 #endif
 
 #endif /* XENCTRL_H */
diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c
index c613545..4d7af3d 100644
--- a/tools/libxc/xc_misc.c
+++ b/tools/libxc/xc_misc.c
@@ -718,6 +718,33 @@ int xc_hvm_inject_trap(
     return rc;
 }
 
+int xc_get_featureset(xc_interface *xch, uint32_t index,
+                      uint32_t *nr_features, uint32_t *featureset)
+{
+    DECLARE_SYSCTL;
+    DECLARE_HYPERCALL_BOUNCE(featureset,
+                             *nr_features * sizeof(*featureset),
+                             XC_HYPERCALL_BUFFER_BOUNCE_OUT);
+    int ret;
+
+    if ( xc_hypercall_bounce_pre(xch, featureset) )
+        return -1;
+
+    sysctl.cmd = XEN_SYSCTL_get_featureset;
+    sysctl.u.featureset.index = index;
+    sysctl.u.featureset.nr_features = *nr_features;
+    set_xen_guest_handle(sysctl.u.featureset.features, featureset);
+
+    ret = do_sysctl(xch, &sysctl);
+
+    xc_hypercall_bounce_post(xch, featureset);
+
+    if ( !ret )
+        *nr_features = sysctl.u.featureset.nr_features;
+
+    return ret;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/tools/ocaml/libs/xc/xenctrl.ml b/tools/ocaml/libs/xc/xenctrl.ml
index b7ba8b7..15c7eb0 100644
--- a/tools/ocaml/libs/xc/xenctrl.ml
+++ b/tools/ocaml/libs/xc/xenctrl.ml
@@ -244,6 +244,9 @@ external version_changeset: handle -> string = "stub_xc_version_changeset"
 external version_capabilities: handle -> string =
   "stub_xc_version_capabilities"
 
+type featureset_index = Featureset_host | Featureset_pv | Featureset_hvm
+external get_featureset : handle -> featureset_index -> int64 array = "stub_xc_get_featureset"
+
 external watchdog : handle -> int -> int32 -> int
   = "stub_xc_watchdog"
 
diff --git a/tools/ocaml/libs/xc/xenctrl.mli b/tools/ocaml/libs/xc/xenctrl.mli
index bc4af56..42d6199 100644
--- a/tools/ocaml/libs/xc/xenctrl.mli
+++ b/tools/ocaml/libs/xc/xenctrl.mli
@@ -148,6 +148,10 @@ external version_compile_info : handle -> compile_info
 external version_changeset : handle -> string = "stub_xc_version_changeset"
 external version_capabilities : handle -> string
   = "stub_xc_version_capabilities"
+
+type featureset_index = Featureset_host | Featureset_pv | Featureset_hvm
+external get_featureset : handle -> featureset_index -> int64 array = "stub_xc_get_featureset"
+
 type core_magic = Magic_hvm | Magic_pv
 type core_header = {
   xch_magic : core_magic;
diff --git a/tools/ocaml/libs/xc/xenctrl_stubs.c b/tools/ocaml/libs/xc/xenctrl_stubs.c
index b7de615..a47473b 100644
--- a/tools/ocaml/libs/xc/xenctrl_stubs.c
+++ b/tools/ocaml/libs/xc/xenctrl_stubs.c
@@ -1220,6 +1220,41 @@ CAMLprim value stub_xc_domain_deassign_device(value xch, value domid, value desc
 	CAMLreturn(Val_unit);
 }
 
+CAMLprim value stub_xc_get_featureset(value xch, value idx)
+{
+	CAMLparam2(xch, idx);
+	CAMLlocal1(bitmap_val);
+
+	/* Safe, because of the global ocaml lock. */
+	static uint32_t fs_len;
+
+	if (fs_len == 0)
+	{
+		int ret = xc_get_featureset(_H(xch), 0, &fs_len, NULL);
+
+		if (ret || (fs_len == 0))
+			failwith_xc(_H(xch));
+	}
+
+	{
+		/* To/from hypervisor to retrieve actual featureset */
+		uint32_t fs[fs_len], len = fs_len;
+		unsigned int i;
+
+		int ret = xc_get_featureset(_H(xch), Int_val(idx), &len, fs);
+
+		if (ret)
+			failwith_xc(_H(xch));
+
+		bitmap_val = caml_alloc(len, 0);
+
+		for (i = 0; i < len; ++i)
+			Store_field(bitmap_val, i, caml_copy_int64(fs[i]));
+	}
+
+	CAMLreturn(bitmap_val);
+}
+
 CAMLprim value stub_xc_watchdog(value xch, value domid, value timeout)
 {
 	CAMLparam3(xch, domid, timeout);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 09/31] xen/x86: Calculate PV featureset
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (7 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 08/31] tools/stubs: Expose host featureset to userspace Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2015-12-22 17:07   ` Jan Beulich
  2015-12-16 21:24 ` [PATCH RFC 10/31] xen/x86: Calculate HVM featureset Andrew Cooper
                   ` (21 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Tim Deegan, Ian Campbell, Jan Beulich

The PV featuremask is the collection of features a PV guest can safely use
(i.e. has support in Xen, or needs no hypervisor support).

The PV guest featureset is then the host featureset, clipped to the PV mask.

As part of this work, I introduced all the remaining bits in leaf 7 which can
be enabled without introducing any further hypervisor support.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Tim Deegan <tim@xen.org>
CC: Ian Campbell <Ian.Campbell@citrix.com>
---
 xen/arch/x86/cpuid.c                     |  12 ++++
 xen/arch/x86/cpuid/cpuid-private.h       |   7 +++
 xen/arch/x86/cpuid/cpuid.c               | 101 ++++++++++++++++++++++++++++++-
 xen/arch/x86/sysctl.c                    |   4 ++
 xen/include/asm-x86/cpuid.h              |   1 +
 xen/include/public/arch-x86/featureset.h |   4 ++
 xen/include/public/sysctl.h              |   1 +
 7 files changed, 129 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c
index 099e145..672bec5 100644
--- a/xen/arch/x86/cpuid.c
+++ b/xen/arch/x86/cpuid.c
@@ -3,13 +3,25 @@
 #include <asm/processor.h>
 #include <asm/cpuid.h>
 
+#include "cpuid/cpuid-private.h"
+
 uint32_t __read_mostly host_featureset[XEN_NR_FEATURESET_ENTRIES];
+uint32_t __read_mostly pv_featureset[XEN_NR_FEATURESET_ENTRIES];
 
 void __init calculate_featuresets(void)
 {
+    unsigned int i;
+
     /* Host featureset. */
     memcpy(host_featureset, boot_cpu_data.x86_capability,
            sizeof(host_featureset));
+
+    /* PV featureset. */
+    for ( i = 0; i < ARRAY_SIZE(pv_featureset); ++i )
+        pv_featureset[i] = host_featureset[i] & pv_featuremask[i];
+
+    /* Unconditionally claim to be able to set the hypervisor bit. */
+    __set_bit(X86_FEATURE_HYPERVISOR, pv_featureset);
 }
 
 /*
diff --git a/xen/arch/x86/cpuid/cpuid-private.h b/xen/arch/x86/cpuid/cpuid-private.h
index a4d582c..4a004d8 100644
--- a/xen/arch/x86/cpuid/cpuid-private.h
+++ b/xen/arch/x86/cpuid/cpuid-private.h
@@ -43,6 +43,13 @@ extern const uint32_t known_features[XEN_NR_FEATURESET_ENTRIES];
 extern const uint32_t inverted_features[XEN_NR_FEATURESET_ENTRIES];
 
 /*
+ * Bitmap of known features which can be exposed to PV guests.  Excludes
+ * features unusable by PV guests, or ones which have no hypervisor side
+ * support.
+ */
+extern const uint32_t pv_featuremask[XEN_NR_FEATURESET_ENTRIES];
+
+/*
  * Local variables:
  * mode: C
  * c-file-style: "BSD"
diff --git a/xen/arch/x86/cpuid/cpuid.c b/xen/arch/x86/cpuid/cpuid.c
index 56993d2..49a8589 100644
--- a/xen/arch/x86/cpuid/cpuid.c
+++ b/xen/arch/x86/cpuid/cpuid.c
@@ -102,7 +102,11 @@ const uint32_t known_features[XEN_NR_FEATURESET_ENTRIES] =
                                             cpufeat_mask(X86_FEATURE_CAT)        |
                                             cpufeat_mask(X86_FEATURE_RDSEED)     |
                                             cpufeat_mask(X86_FEATURE_ADX)        |
-                                            cpufeat_mask(X86_FEATURE_SMAP)),
+                                            cpufeat_mask(X86_FEATURE_SMAP)       |
+                                            cpufeat_mask(X86_FEATURE_PCOMMIT)    |
+                                            cpufeat_mask(X86_FEATURE_CLFLUSHOPT) |
+                                            cpufeat_mask(X86_FEATURE_CLWB)       |
+                                            cpufeat_mask(X86_FEATURE_SHA)),
 
     [cpufeat_word(X86_FEATURE_PREFETCHWT1)] = (cpufeat_mask(X86_FEATURE_PREFETCHWT1)),
 
@@ -116,6 +120,101 @@ const uint32_t inverted_features[XEN_NR_FEATURESET_ENTRIES] =
     [cpufeat_word(X86_FEATURE_FPU_SEL)] = cpufeat_mask(X86_FEATURE_FPU_SEL),
 };
 
+#define PV_FEATUREMASK_1d                       \
+    (cpufeat_mask(X86_FEATURE_FPU)    |         \
+     cpufeat_mask(X86_FEATURE_DE)     |         \
+     cpufeat_mask(X86_FEATURE_TSC)    |         \
+     cpufeat_mask(X86_FEATURE_MSR)    |         \
+     cpufeat_mask(X86_FEATURE_PAE)    |         \
+     cpufeat_mask(X86_FEATURE_MCE)    |         \
+     cpufeat_mask(X86_FEATURE_CX8)    |         \
+     cpufeat_mask(X86_FEATURE_APIC)   |         \
+     cpufeat_mask(X86_FEATURE_SEP)    |         \
+     cpufeat_mask(X86_FEATURE_MCA)    |         \
+     cpufeat_mask(X86_FEATURE_CMOV)   |         \
+     cpufeat_mask(X86_FEATURE_PAT)    |         \
+     cpufeat_mask(X86_FEATURE_CLFLSH) |         \
+     cpufeat_mask(X86_FEATURE_ACPI)   |         \
+     cpufeat_mask(X86_FEATURE_MMX)    |         \
+     cpufeat_mask(X86_FEATURE_FXSR)   |         \
+     cpufeat_mask(X86_FEATURE_XMM)    |         \
+     cpufeat_mask(X86_FEATURE_XMM2))
+
+#define PV_FEATUREMASK_1c                       \
+    (cpufeat_mask(X86_FEATURE_XMM3)      |      \
+     cpufeat_mask(X86_FEATURE_PCLMULQDQ) |      \
+     cpufeat_mask(X86_FEATURE_SSSE3)     |      \
+     cpufeat_mask(X86_FEATURE_FMA)       |      \
+     cpufeat_mask(X86_FEATURE_CX16)      |      \
+     cpufeat_mask(X86_FEATURE_SSE4_1)    |      \
+     cpufeat_mask(X86_FEATURE_SSE4_2)    |      \
+     cpufeat_mask(X86_FEATURE_X2APIC)    |      \
+     cpufeat_mask(X86_FEATURE_MOVBE)     |      \
+     cpufeat_mask(X86_FEATURE_POPCNT)    |      \
+     cpufeat_mask(X86_FEATURE_AES)       |      \
+     cpufeat_mask(X86_FEATURE_XSAVE)     |      \
+     cpufeat_mask(X86_FEATURE_AVX)       |      \
+     cpufeat_mask(X86_FEATURE_F16C)      |      \
+     cpufeat_mask(X86_FEATURE_RDRAND)    |      \
+     cpufeat_mask(X86_FEATURE_HYPERVISOR))
+
+#define PV_FEATUREMASK_e1d                      \
+    ((PV_FEATUREMASK_1d & SHARED_1d)    |       \
+     cpufeat_mask(X86_FEATURE_SYSCALL)  |       \
+     cpufeat_mask(X86_FEATURE_MP)       |       \
+     cpufeat_mask(X86_FEATURE_NX)       |       \
+     cpufeat_mask(X86_FEATURE_MMXEXT)   |       \
+     cpufeat_mask(X86_FEATURE_FFXSR)    |       \
+     cpufeat_mask(X86_FEATURE_LM)       |       \
+     cpufeat_mask(X86_FEATURE_3DNOWEXT) |       \
+     cpufeat_mask(X86_FEATURE_3DNOW))
+
+#define PV_FEATUREMASK_e1c                      \
+    (cpufeat_mask(X86_FEATURE_LAHF_LM)       |  \
+     cpufeat_mask(X86_FEATURE_ABM)           |  \
+     cpufeat_mask(X86_FEATURE_SSE4A)         |  \
+     cpufeat_mask(X86_FEATURE_MISALIGNSSE)   |  \
+     cpufeat_mask(X86_FEATURE_3DNOWPREFETCH) |  \
+     cpufeat_mask(X86_FEATURE_XOP)           |  \
+     cpufeat_mask(X86_FEATURE_LWP)           |  \
+     cpufeat_mask(X86_FEATURE_FMA4)          |  \
+     cpufeat_mask(X86_FEATURE_TBM)           |  \
+     cpufeat_mask(X86_FEATURE_DBEXT))
+
+#define PV_FEATUREMASK_Da1                      \
+    (cpufeat_mask(X86_FEATURE_XSAVEOPT) |       \
+     cpufeat_mask(X86_FEATURE_XSAVEC)   |       \
+     cpufeat_mask(X86_FEATURE_XGETBV1))
+
+#define PV_FEATUREMASK_7b0                      \
+    (cpufeat_mask(X86_FEATURE_FSGSBASE)   |     \
+     cpufeat_mask(X86_FEATURE_BMI1)       |     \
+     cpufeat_mask(X86_FEATURE_HLE)        |     \
+     cpufeat_mask(X86_FEATURE_AVX2)       |     \
+     cpufeat_mask(X86_FEATURE_BMI2)       |     \
+     cpufeat_mask(X86_FEATURE_ERMS)       |     \
+     cpufeat_mask(X86_FEATURE_RTM)        |     \
+     cpufeat_mask(X86_FEATURE_RDSEED)     |     \
+     cpufeat_mask(X86_FEATURE_ADX)        |     \
+     cpufeat_mask(X86_FEATURE_PCOMMIT)    |     \
+     cpufeat_mask(X86_FEATURE_CLFLUSHOPT) |     \
+     cpufeat_mask(X86_FEATURE_CLWB)       |     \
+     cpufeat_mask(X86_FEATURE_SHA))
+
+#define PV_FEATUREMASK_7c0                      \
+    (cpufeat_mask(X86_FEATURE_PREFETCHWT1))
+
+const uint32_t pv_featuremask[XEN_NR_FEATURESET_ENTRIES] =
+{
+    PV_FEATUREMASK_1d,
+    PV_FEATUREMASK_1c,
+    PV_FEATUREMASK_e1d,
+    PV_FEATUREMASK_e1c,
+    PV_FEATUREMASK_Da1,
+    PV_FEATUREMASK_7b0,
+    PV_FEATUREMASK_7c0,
+};
+
 /*
  * Local variables:
  * mode: C
diff --git a/xen/arch/x86/sysctl.c b/xen/arch/x86/sysctl.c
index 1f483b8..34ffe43 100644
--- a/xen/arch/x86/sysctl.c
+++ b/xen/arch/x86/sysctl.c
@@ -215,6 +215,10 @@ long arch_do_sysctl(
             featureset = host_featureset;
             break;
 
+        case XEN_SYSCTL_featureset_pv:
+            featureset = pv_featureset;
+            break;
+
         default:
             featureset = NULL;
             break;
diff --git a/xen/include/asm-x86/cpuid.h b/xen/include/asm-x86/cpuid.h
index c303c74..6a7357f 100644
--- a/xen/include/asm-x86/cpuid.h
+++ b/xen/include/asm-x86/cpuid.h
@@ -6,6 +6,7 @@
 #include <public/sysctl.h>
 
 extern uint32_t host_featureset[XEN_NR_FEATURESET_ENTRIES];
+extern uint32_t pv_featureset[XEN_NR_FEATURESET_ENTRIES];
 
 void calculate_featuresets(void);
 
diff --git a/xen/include/public/arch-x86/featureset.h b/xen/include/public/arch-x86/featureset.h
index f48ad5b..0e010e9 100644
--- a/xen/include/public/arch-x86/featureset.h
+++ b/xen/include/public/arch-x86/featureset.h
@@ -187,6 +187,10 @@
 #define X86_FEATURE_RDSEED        ( 5*32+18) /* RDSEED instruction */
 #define X86_FEATURE_ADX           ( 5*32+19) /* ADCX, ADOX instructions */
 #define X86_FEATURE_SMAP          ( 5*32+20) /* Supervisor Mode Access Prevention */
+#define X86_FEATURE_PCOMMIT       ( 5*32+22) /* PCOMMIT instruction */
+#define X86_FEATURE_CLFLUSHOPT    ( 5*32+23) /* CLFLUSHOPT instruction */
+#define X86_FEATURE_CLWB          ( 5*32+24) /* CLWB instruction */
+#define X86_FEATURE_SHA           ( 5*32+29) /* SHA1 & SHA256 instructions */
 
 /* Intel-defined CPU features, CPUID level 0x00000007:0.ecx, word 6 */
 #define X86_FEATURE_PREFETCHWT1   ( 6*32+ 0) /* PREFETCHWT1 instruction */
diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
index dfde433..33ba66b 100644
--- a/xen/include/public/sysctl.h
+++ b/xen/include/public/sysctl.h
@@ -773,6 +773,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_sysctl_tmem_op_t);
  */
 struct xen_sysctl_featureset {
 #define XEN_SYSCTL_featureset_host      0
+#define XEN_SYSCTL_featureset_pv        1
     uint32_t index;       /* IN: Which featureset to query? */
     uint32_t nr_features; /* IN/OUT: Number of entries in/written to
                            * 'features', or the maximum number of features if
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 10/31] xen/x86: Calculate HVM featureset
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (8 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 09/31] xen/x86: Calculate PV featureset Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2015-12-22 17:11   ` Jan Beulich
  2015-12-16 21:24 ` [PATCH RFC 11/31] xen/x86: Calculate Raw featureset Andrew Cooper
                   ` (20 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Tim Deegan, Ian Campbell, Jan Beulich

For HVM guests, there are two different featuresets, depending on whether hap
or shadow mode is used.

HVM Shadow guests are strictly more capable than PV guests, and HVM HAP are
strictly more capable than HVM Shadow; this is represented in the way the HVM
shadow and HAP masks are expressed.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Tim Deegan <tim@xen.org>
CC: Ian Campbell <Ian.Campbell@citrix.com>
---
 xen/arch/x86/cpuid.c               | 23 +++++++++++
 xen/arch/x86/cpuid/cpuid-private.h |  8 ++++
 xen/arch/x86/cpuid/cpuid.c         | 84 ++++++++++++++++++++++++++++++++++++++
 xen/arch/x86/sysctl.c              |  4 ++
 xen/include/asm-x86/cpuid.h        |  1 +
 xen/include/public/sysctl.h        |  1 +
 6 files changed, 121 insertions(+)

diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c
index 672bec5..1a8b0ff 100644
--- a/xen/arch/x86/cpuid.c
+++ b/xen/arch/x86/cpuid.c
@@ -2,11 +2,13 @@
 #include <xen/init.h>
 #include <asm/processor.h>
 #include <asm/cpuid.h>
+#include <asm/hvm/hvm.h>
 
 #include "cpuid/cpuid-private.h"
 
 uint32_t __read_mostly host_featureset[XEN_NR_FEATURESET_ENTRIES];
 uint32_t __read_mostly pv_featureset[XEN_NR_FEATURESET_ENTRIES];
+uint32_t __read_mostly hvm_featureset[XEN_NR_FEATURESET_ENTRIES];
 
 void __init calculate_featuresets(void)
 {
@@ -22,6 +24,27 @@ void __init calculate_featuresets(void)
 
     /* Unconditionally claim to be able to set the hypervisor bit. */
     __set_bit(X86_FEATURE_HYPERVISOR, pv_featureset);
+
+    /* HVM featureset. */
+    if ( hvm_enabled )
+    {
+        const uint32_t *hvm_featuremask = hvm_funcs.hap_supported
+            ? hvm_hap_featuremask : hvm_shadow_featuremask;
+
+        for ( i = 0; i < ARRAY_SIZE(hvm_featureset); ++i )
+            hvm_featureset[i] = host_featureset[i] & hvm_featuremask[i];
+
+        /* Unconditionally claim to be able to set the hypervisor bit. */
+        __set_bit(X86_FEATURE_HYPERVISOR, hvm_featureset);
+
+        /*
+         * On AMD, PV guests are entirely unable to use 'sysenter' as Xen runs
+         * in long mode, but HVM guests are able if running in protected mode.
+         */
+        if ( (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) &&
+             !test_bit(X86_FEATURE_SEP, boot_cpu_data.x86_capability) )
+            __set_bit(X86_FEATURE_SEP, hvm_featureset);
+    }
 }
 
 /*
diff --git a/xen/arch/x86/cpuid/cpuid-private.h b/xen/arch/x86/cpuid/cpuid-private.h
index 4a004d8..014ec43 100644
--- a/xen/arch/x86/cpuid/cpuid-private.h
+++ b/xen/arch/x86/cpuid/cpuid-private.h
@@ -50,6 +50,14 @@ extern const uint32_t inverted_features[XEN_NR_FEATURESET_ENTRIES];
 extern const uint32_t pv_featuremask[XEN_NR_FEATURESET_ENTRIES];
 
 /*
+ * Bitmap of known features which can be exposed to HVM guests.  Excludes
+ * features unusable by HVM guests, or ones which have no hypervisor side
+ * support.  The available featureset is less if shadow paging is used.
+ */
+extern const uint32_t hvm_shadow_featuremask[XEN_NR_FEATURESET_ENTRIES];
+extern const uint32_t hvm_hap_featuremask[XEN_NR_FEATURESET_ENTRIES];
+
+/*
  * Local variables:
  * mode: C
  * c-file-style: "BSD"
diff --git a/xen/arch/x86/cpuid/cpuid.c b/xen/arch/x86/cpuid/cpuid.c
index 49a8589..25385d4 100644
--- a/xen/arch/x86/cpuid/cpuid.c
+++ b/xen/arch/x86/cpuid/cpuid.c
@@ -215,6 +215,90 @@ const uint32_t pv_featuremask[XEN_NR_FEATURESET_ENTRIES] =
     PV_FEATUREMASK_7c0,
 };
 
+#define HVM_SHADOW_FEATUREMASK_1d               \
+    (PV_FEATUREMASK_1d               |          \
+     cpufeat_mask(X86_FEATURE_VME)   |          \
+     cpufeat_mask(X86_FEATURE_PSE)   |          \
+     cpufeat_mask(X86_FEATURE_MTRR)  |          \
+     cpufeat_mask(X86_FEATURE_PGE)   |          \
+     cpufeat_mask(X86_FEATURE_PSE36))
+
+#define HVM_SHADOW_FEATUREMASK_1c               \
+    (PV_FEATUREMASK_1c                      |   \
+     cpufeat_mask(X86_FEATURE_VMXE)         |   \
+     cpufeat_mask(X86_FEATURE_TSC_DEADLINE))
+
+#define HVM_SHADOW_FEATUREMASK_e1d              \
+    (PV_FEATUREMASK_e1d                      |  \
+     (HVM_SHADOW_FEATUREMASK_1d & SHARED_1d) |  \
+     cpufeat_mask(X86_FEATURE_RDTSCP))
+
+#define HVM_SHADOW_FEATUREMASK_e1c              \
+    (PV_FEATUREMASK_e1c                   |     \
+     cpufeat_mask(X86_FEATURE_SVM)        |     \
+     cpufeat_mask(X86_FEATURE_CR8_LEGACY) |     \
+     cpufeat_mask(X86_FEATURE_IBS))
+
+#define HVM_SHADOW_FEATUREMASK_Da1              \
+    (PV_FEATUREMASK_Da1               |         \
+     cpufeat_mask(X86_FEATURE_XSAVES))
+
+#define HVM_SHADOW_FEATUREMASK_7b0              \
+    (PV_FEATUREMASK_7b0                   |     \
+     cpufeat_mask(X86_FEATURE_TSC_ADJUST) |     \
+     cpufeat_mask(X86_FEATURE_SMEP)       |     \
+     cpufeat_mask(X86_FEATURE_SMAP))
+
+#define HVM_SHADOW_FEATUREMASK_7c0              \
+    (PV_FEATUREMASK_7c0)
+
+const uint32_t hvm_shadow_featuremask[XEN_NR_FEATURESET_ENTRIES] =
+{
+    HVM_SHADOW_FEATUREMASK_1d,
+    HVM_SHADOW_FEATUREMASK_1c,
+    HVM_SHADOW_FEATUREMASK_e1d,
+    HVM_SHADOW_FEATUREMASK_e1c,
+    HVM_SHADOW_FEATUREMASK_Da1,
+    HVM_SHADOW_FEATUREMASK_7b0,
+    HVM_SHADOW_FEATUREMASK_7c0,
+};
+
+#define HVM_HAP_FEATUREMASK_1d                  \
+    (HVM_SHADOW_FEATUREMASK_1d)
+
+#define HVM_HAP_FEATUREMASK_1c                  \
+    (HVM_SHADOW_FEATUREMASK_1c     |            \
+     cpufeat_mask(X86_FEATURE_PCID))
+
+#define HVM_HAP_FEATUREMASK_e1d                 \
+    (HVM_SHADOW_FEATUREMASK_e1d           |     \
+     (HVM_HAP_FEATUREMASK_1d & SHARED_1d) |     \
+     cpufeat_mask(X86_FEATURE_PAGE1GB))
+
+#define HVM_HAP_FEATUREMASK_e1c                 \
+    (HVM_SHADOW_FEATUREMASK_e1c)
+
+#define HVM_HAP_FEATUREMASK_Da1                 \
+    (HVM_SHADOW_FEATUREMASK_Da1)
+
+#define HVM_HAP_FEATUREMASK_7b0                 \
+    (HVM_SHADOW_FEATUREMASK_7b0        |        \
+     cpufeat_mask(X86_FEATURE_INVPCID))
+
+#define HVM_HAP_FEATUREMASK_7c0                 \
+    (HVM_SHADOW_FEATUREMASK_7c0)
+
+const uint32_t hvm_hap_featuremask[XEN_NR_FEATURESET_ENTRIES] =
+{
+    HVM_HAP_FEATUREMASK_1d,
+    HVM_HAP_FEATUREMASK_1c,
+    HVM_HAP_FEATUREMASK_e1d,
+    HVM_HAP_FEATUREMASK_e1c,
+    HVM_HAP_FEATUREMASK_Da1,
+    HVM_HAP_FEATUREMASK_7b0,
+    HVM_HAP_FEATUREMASK_7c0,
+};
+
 /*
  * Local variables:
  * mode: C
diff --git a/xen/arch/x86/sysctl.c b/xen/arch/x86/sysctl.c
index 34ffe43..0ba0f5e 100644
--- a/xen/arch/x86/sysctl.c
+++ b/xen/arch/x86/sysctl.c
@@ -219,6 +219,10 @@ long arch_do_sysctl(
             featureset = pv_featureset;
             break;
 
+        case XEN_SYSCTL_featureset_hvm:
+            featureset = hvm_featureset;
+            break;
+
         default:
             featureset = NULL;
             break;
diff --git a/xen/include/asm-x86/cpuid.h b/xen/include/asm-x86/cpuid.h
index 6a7357f..b6498b9 100644
--- a/xen/include/asm-x86/cpuid.h
+++ b/xen/include/asm-x86/cpuid.h
@@ -7,6 +7,7 @@
 
 extern uint32_t host_featureset[XEN_NR_FEATURESET_ENTRIES];
 extern uint32_t pv_featureset[XEN_NR_FEATURESET_ENTRIES];
+extern uint32_t hvm_featureset[XEN_NR_FEATURESET_ENTRIES];
 
 void calculate_featuresets(void);
 
diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
index 33ba66b..8728950 100644
--- a/xen/include/public/sysctl.h
+++ b/xen/include/public/sysctl.h
@@ -774,6 +774,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_sysctl_tmem_op_t);
 struct xen_sysctl_featureset {
 #define XEN_SYSCTL_featureset_host      0
 #define XEN_SYSCTL_featureset_pv        1
+#define XEN_SYSCTL_featureset_hvm       2
     uint32_t index;       /* IN: Which featureset to query? */
     uint32_t nr_features; /* IN/OUT: Number of entries in/written to
                            * 'features', or the maximum number of features if
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 11/31] xen/x86: Calculate Raw featureset
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (9 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 10/31] xen/x86: Calculate HVM featureset Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2015-12-22 17:14   ` Jan Beulich
  2015-12-16 21:24 ` [PATCH RFC 12/31] tools: Utility for dealing with featuresets Andrew Cooper
                   ` (19 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Tim Deegan, Ian Campbell, Jan Beulich

Calculate and expose the raw featureset to userspace.  This is for
informational purposes; the difference between the raw and the host
featuresets are the features Xen has specifically chosen not to use.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Tim Deegan <tim@xen.org>
CC: Ian Campbell <Ian.Campbell@citrix.com>
---
 xen/arch/x86/cpuid.c        | 36 +++++++++++++++++++++++++++++++++++-
 xen/arch/x86/sysctl.c       |  4 ++++
 xen/include/asm-x86/cpuid.h |  1 +
 xen/include/public/sysctl.h |  1 +
 4 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c
index 1a8b0ff..e4da820 100644
--- a/xen/arch/x86/cpuid.c
+++ b/xen/arch/x86/cpuid.c
@@ -7,12 +7,46 @@
 #include "cpuid/cpuid-private.h"
 
 uint32_t __read_mostly host_featureset[XEN_NR_FEATURESET_ENTRIES];
+uint32_t __read_mostly raw_featureset[XEN_NR_FEATURESET_ENTRIES];
 uint32_t __read_mostly pv_featureset[XEN_NR_FEATURESET_ENTRIES];
 uint32_t __read_mostly hvm_featureset[XEN_NR_FEATURESET_ENTRIES];
 
 void __init calculate_featuresets(void)
 {
-    unsigned int i;
+    unsigned int i, max, tmp;
+
+    /* Raw featureset. */
+    max = cpuid_eax(0);
+
+    if ( max >= 1 )
+        cpuid(0x1, &tmp, &tmp,
+              &raw_featureset[XEN_FEATURESET_1c],
+              &raw_featureset[XEN_FEATURESET_1d]);
+    if ( max >= 7 )
+        cpuid_count(0x7, 0, &tmp,
+                    &raw_featureset[XEN_FEATURESET_7b0],
+                    &raw_featureset[XEN_FEATURESET_7c0],
+                    &tmp);
+    if ( max >= 0xd )
+        cpuid_count(0xd, 1,
+                    &raw_featureset[XEN_FEATURESET_Da1],
+                    &tmp, &tmp, &tmp);
+
+    max = cpuid_eax(0x80000000);
+    if ( max >= 0x80000001 )
+        cpuid(0x80000001, &tmp, &tmp,
+              &raw_featureset[XEN_FEATURESET_e1c],
+              &raw_featureset[XEN_FEATURESET_e1d]);
+    if ( max >= 0x80000007 )
+        cpuid(0x80000007, &tmp, &tmp, &tmp,
+              &raw_featureset[XEN_FEATURESET_e7d]);
+    if ( max >= 0x80000008 )
+        cpuid(0x80000008, &tmp,
+              &raw_featureset[XEN_FEATURESET_e8b],
+              &tmp, &tmp);
+
+    for ( i = 0; i < ARRAY_SIZE(raw_featureset); ++i )
+        raw_featureset[i] ^= inverted_features[i];
 
     /* Host featureset. */
     memcpy(host_featureset, boot_cpu_data.x86_capability,
diff --git a/xen/arch/x86/sysctl.c b/xen/arch/x86/sysctl.c
index 0ba0f5e..50b2fd4 100644
--- a/xen/arch/x86/sysctl.c
+++ b/xen/arch/x86/sysctl.c
@@ -223,6 +223,10 @@ long arch_do_sysctl(
             featureset = hvm_featureset;
             break;
 
+        case XEN_SYSCTL_featureset_raw:
+            featureset = raw_featureset;
+            break;
+
         default:
             featureset = NULL;
             break;
diff --git a/xen/include/asm-x86/cpuid.h b/xen/include/asm-x86/cpuid.h
index b6498b9..6b61400 100644
--- a/xen/include/asm-x86/cpuid.h
+++ b/xen/include/asm-x86/cpuid.h
@@ -6,6 +6,7 @@
 #include <public/sysctl.h>
 
 extern uint32_t host_featureset[XEN_NR_FEATURESET_ENTRIES];
+extern uint32_t raw_featureset[XEN_NR_FEATURESET_ENTRIES];
 extern uint32_t pv_featureset[XEN_NR_FEATURESET_ENTRIES];
 extern uint32_t hvm_featureset[XEN_NR_FEATURESET_ENTRIES];
 
diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
index 8728950..3119b7b 100644
--- a/xen/include/public/sysctl.h
+++ b/xen/include/public/sysctl.h
@@ -775,6 +775,7 @@ struct xen_sysctl_featureset {
 #define XEN_SYSCTL_featureset_host      0
 #define XEN_SYSCTL_featureset_pv        1
 #define XEN_SYSCTL_featureset_hvm       2
+#define XEN_SYSCTL_featureset_raw       3
     uint32_t index;       /* IN: Which featureset to query? */
     uint32_t nr_features; /* IN/OUT: Number of entries in/written to
                            * 'features', or the maximum number of features if
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 12/31] tools: Utility for dealing with featuresets
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (10 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 11/31] xen/x86: Calculate Raw featureset Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2016-01-05 15:17   ` Ian Campbell
  2016-01-06 10:40   ` Ian Campbell
  2015-12-16 21:24 ` [PATCH RFC 13/31] tools/libxc: Wire a featureset through to cpuid policy logic Andrew Cooper
                   ` (18 subsequent siblings)
  30 siblings, 2 replies; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Ian Jackson, Ian Campbell, Wei Liu

It is able to reports the current featuresets; both the static masks and
dynamic featuresets from Xen, or to decode an arbitrary featureset into
`/proc/cpuinfo` style strings.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Ian Campbell <Ian.Campbell@citrix.com>
CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
CC: Wei Liu <wei.liu2@citrix.com>
---
 .gitignore                         |   1 +
 tools/libxc/Makefile               |   6 +
 tools/misc/Makefile                |   6 +
 tools/misc/xen-cpuid.c             | 392 +++++++++++++++++++++++++++++++++++++
 xen/arch/x86/cpuid/cpuid-private.h |   9 +-
 5 files changed, 413 insertions(+), 1 deletion(-)
 create mode 100644 tools/misc/xen-cpuid.c

diff --git a/.gitignore b/.gitignore
index 9ead7c4..63944b5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -167,6 +167,7 @@ tools/misc/cpuperf/cpuperf-perfcntr
 tools/misc/cpuperf/cpuperf-xen
 tools/misc/xc_shadow
 tools/misc/xen_cpuperf
+tools/misc/xen-cpuid
 tools/misc/xen-detect
 tools/misc/xen-tmem-list-parse
 tools/misc/xenperf
diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
index a0f899b..83547e1 100644
--- a/tools/libxc/Makefile
+++ b/tools/libxc/Makefile
@@ -79,6 +79,12 @@ GUEST_SRCS-y += $(ELF_SRCS-y)
 $(patsubst %.c,%.o,$(ELF_SRCS-y)): CFLAGS += -Wno-pointer-sign
 $(patsubst %.c,%.opic,$(ELF_SRCS-y)): CFLAGS += -Wno-pointer-sign
 
+ifeq ($(CONFIG_X86),y)
+vpath %.c ../../xen/arch/x86/cpuid
+CFLAGS += -I../../xen/arch/x86/cpuid
+CTRL_SRCS-y += cpuid.c
+endif
+
 # new domain builder
 GUEST_SRCS-y                 += xc_dom_core.c xc_dom_boot.c
 GUEST_SRCS-y                 += xc_dom_elfloader.c
diff --git a/tools/misc/Makefile b/tools/misc/Makefile
index c4490f3..eb7649d 100644
--- a/tools/misc/Makefile
+++ b/tools/misc/Makefile
@@ -9,6 +9,7 @@ CFLAGS += $(CFLAGS_xeninclude)
 CFLAGS += $(CFLAGS_libxenstore)
 
 # Everything to be installed in regular bin/
+INSTALL_BIN-$(CONFIG_X86)      += xen-cpuid
 INSTALL_BIN-$(CONFIG_X86)      += xen-detect
 INSTALL_BIN                    += xencons
 INSTALL_BIN                    += xencov_split
@@ -67,6 +68,11 @@ clean:
 .PHONY: distclean
 distclean: clean
 
+xen-cpuid.o: CFLAGS += -I$(XEN_ROOT)/xen/arch/x86/cpuid
+xen-cpuid.o: CFLAGS += -I$(XEN_ROOT)/tools/libxc
+xen-cpuid: xen-cpuid.o
+	$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS)
+
 xen-hvmctx: xen-hvmctx.o
 	$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS)
 
diff --git a/tools/misc/xen-cpuid.c b/tools/misc/xen-cpuid.c
new file mode 100644
index 0000000..e0cd6bb
--- /dev/null
+++ b/tools/misc/xen-cpuid.c
@@ -0,0 +1,392 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <err.h>
+#include <getopt.h>
+#include <string.h>
+
+#include <xenctrl.h>
+#include "cpuid-private.h"
+
+static uint32_t nr_features = XEN_NR_FEATURESET_ENTRIES;
+
+static const char *str_1d[32] =
+{
+    [ 0] = "fpu",  [ 1] = "vme",
+    [ 2] = "de",   [ 3] = "pse",
+    [ 4] = "tsc",  [ 5] = "msr",
+    [ 6] = "pae",  [ 7] = "mce",
+    [ 8] = "cx8",  [ 9] = "apic",
+    [10] = "REZ",  [11] = "sysenter",
+    [12] = "mtrr", [13] = "pge",
+    [14] = "mca",  [15] = "cmov",
+    [16] = "pat",  [17] = "pse36",
+    [18] = "psn",  [19] = "clflsh",
+    [20] = "REZ",  [21] = "ds",
+    [22] = "acpi", [23] = "mmx",
+    [24] = "fxsr", [25] = "sse",
+    [26] = "sse2", [27] = "ss",
+    [28] = "htt",  [29] = "tm",
+    [30] = "ia64", [31] = "pbe",
+};
+
+static const char *str_1c[32] =
+{
+    [ 0] = "sse3",    [ 1] = "pclmulqdq",
+    [ 2] = "dtes64",  [ 3] = "monitor",
+    [ 4] = "ds-cpl",  [ 5] = "vmx",
+    [ 6] = "smx",     [ 7] = "est",
+    [ 8] = "tm2",     [ 9] = "ssse3",
+    [10] = "cntx-id", [11] = "sdgb",
+    [12] = "fma",     [13] = "cx16",
+    [14] = "xtpr",    [15] = "pdcm",
+    [16] = "REZ",     [17] = "pcid",
+    [18] = "dca",     [19] = "sse41",
+    [20] = "sse42",   [21] = "x2apic",
+    [22] = "movebe",  [23] = "popcnt",
+    [24] = "tsc-dl",  [25] = "aes",
+    [26] = "xsave",   [27] = "osxsave",
+    [28] = "avx",     [29] = "f16c",
+    [30] = "rdrnd",   [31] = "hyper",
+};
+
+static const char *str_e1d[32] =
+{
+    [ 0] = "fpu",    [ 1] = "vme",
+    [ 2] = "de",     [ 3] = "pse",
+    [ 4] = "tsc",    [ 5] = "msr",
+    [ 6] = "pae",    [ 7] = "mce",
+    [ 8] = "cx8",    [ 9] = "apic",
+    [10] = "REZ",    [11] = "syscall",
+    [12] = "mtrr",   [13] = "pge",
+    [14] = "mca",    [15] = "cmov",
+    [16] = "fcmov",  [17] = "pse36",
+    [18] = "REZ",    [19] = "mp",
+    [20] = "nx",     [21] = "REZ",
+    [22] = "mmx+",   [23] = "mmx",
+    [24] = "fxsr",   [25] = "fxsr+",
+    [26] = "pg1g",   [27] = "rdtscp",
+    [28] = "REZ",    [29] = "lm",
+    [30] = "3dnow+", [31] = "3dnow",
+};
+
+static const char *str_e1c[32] =
+{
+    [ 0] = "lahf_lm",    [ 1] = "cmp",
+    [ 2] = "svm",        [ 3] = "extapic",
+    [ 4] = "cr8d",       [ 5] = "lzcnt",
+    [ 6] = "sse4a",      [ 7] = "msse",
+    [ 8] = "3dnowpf",    [ 9] = "osvw",
+    [10] = "ibs",        [11] = "xop",
+    [12] = "skinit",     [13] = "wdt",
+    [14] = "REZ",        [15] = "lwp",
+    [16] = "fma4",       [17] = "tce",
+    [18] = "REZ",        [19] = "nodeid",
+    [20] = "REZ",        [21] = "tbm",
+    [22] = "topoext",    [23] = "perfctr_core",
+    [24] = "perfctr_nb", [25] = "REZ",
+    [26] = "dbx",        [27] = "perftsc",
+    [28] = "pcx_l2i",    [29] = "monitorx",
+
+    [30 ... 31] = "REZ",
+};
+
+static const char *str_7b0[32] =
+{
+    [ 0] = "fsgsbase", [ 1] = "tsc-adj",
+    [ 2] = "sgx",      [ 3] = "bmi1",
+    [ 4] = "hle",      [ 5] = "avx2",
+    [ 6] = "REZ",      [ 7] = "smep",
+    [ 8] = "bmi2",     [ 9] = "erms",
+    [10] = "invpcid",  [11] = "rtm",
+    [12] = "pqm",      [13] = "depfpp",
+    [14] = "mpx",      [15] = "pqe",
+    [16] = "avx512f",  [17] = "avx512dq",
+    [18] = "rdseed",   [19] = "adx",
+    [20] = "smap",     [21] = "avx512ifma",
+    [22] = "pcomit",   [23] = "clflushopt",
+    [24] = "clwb",     [25] = "pt",
+    [26] = "avx512pf", [27] = "avx512er",
+    [28] = "avx512cd", [29] = "sha",
+    [30] = "avx512bw", [31] = "avx512vl",
+};
+
+static const char *str_Da1[32] =
+{
+    [ 0] = "xsaveopt", [ 1] = "xsavec",
+    [ 2] = "xgetbv1",  [ 3] = "xsaves",
+
+    [4 ... 31] = "REZ",
+};
+
+static const char *str_7c0[32] =
+{
+    [ 0] = "prechwt1", [ 1] = "avx512vbmi",
+    [ 2] = "REZ",      [ 3] = "pku",
+    [ 4] = "ospke",
+
+    [5 ... 31] = "REZ",
+};
+
+static const char *str_e7d[32] =
+{
+    [0 ... 7] = "REZ",
+
+    [ 8] = "itsc",
+
+    [9 ... 31] = "REZ",
+};
+
+static const char *str_e8b[32] =
+{
+    [ 0] = "clzero",
+
+    [1 ... 31] = "REZ",
+};
+
+static struct {
+    const char *name;
+    const char *abbr;
+    const char **strs;
+} decodes[] =
+{
+    [XEN_FEATURESET_1d]  = { "0x00000001.edx",   "1d",  str_1d },
+    [XEN_FEATURESET_1c]  = { "0x00000001.ecx",   "1c",  str_1c },
+    [XEN_FEATURESET_e1d] = { "0x80000001.edx",   "e1d", str_e1d },
+    [XEN_FEATURESET_e1c] = { "0x80000001.ecx",   "e1c", str_e1c },
+    [XEN_FEATURESET_Da1] = { "0x0000000d:1.eax", "Da1", str_Da1 },
+    [XEN_FEATURESET_7b0] = { "0x00000007:0.ebx", "7b0", str_7b0 },
+    [XEN_FEATURESET_7c0] = { "0x00000007:0.ecx", "7c0", str_7c0 },
+    [XEN_FEATURESET_e7d] = { "0x80000007.edx",   "e7d", str_e7d },
+    [XEN_FEATURESET_e8b] = { "0x80000008.ebx",   "e8b", str_e8b },
+};
+
+#define COL_ALIGN "18"
+
+static struct fsinfo {
+    const char *name;
+    uint32_t len;
+    uint32_t *fs;
+} featuresets[] =
+{
+    [XEN_SYSCTL_featureset_host] = { "Host", 0, NULL },
+    [XEN_SYSCTL_featureset_pv]   = { "PV",   0, NULL },
+    [XEN_SYSCTL_featureset_hvm]  = { "HVM",  0, NULL },
+    [XEN_SYSCTL_featureset_raw]  = { "Raw",  0, NULL },
+};
+
+static void dump_leaf(uint32_t leaf, const char **strs)
+{
+    unsigned i;
+
+    if ( !strs )
+    {
+        printf(" ???");
+        return;
+    }
+
+    for ( i = 0; i < 32; ++i )
+        if ( leaf & (1u << i) )
+            printf(" %s", strs[i] ?: "???" );
+}
+
+static void decode_featureset(const uint32_t *features,
+                              const uint32_t length,
+                              const char *name,
+                              bool detail)
+{
+    unsigned int i;
+
+    printf("%-"COL_ALIGN"s        ", name);
+    for ( i = 0; i < length; ++i )
+        printf("%08x%c", features[i],
+               i < length - 1 ? ':' : '\n');
+
+    if ( !detail )
+        return;
+
+    for ( i = 0; i < length && i < ARRAY_SIZE(decodes); ++i )
+    {
+        printf("  [%02u] %-"COL_ALIGN"s", i, decodes[i].name ?: "<UNKNOWN>");
+        if ( decodes[i].name )
+            dump_leaf(features[i], decodes[i].strs);
+        printf("\n");
+    }
+}
+
+static void get_featureset(xc_interface *xch, unsigned int idx)
+{
+    struct fsinfo *f = &featuresets[idx];
+
+    f->len = nr_features;
+    f->fs = calloc(nr_features, sizeof(*f->fs));
+
+    if ( !f->fs )
+        err(1, "calloc(, featureset)");
+
+    if ( xc_get_featureset(xch, idx, &f->len, f->fs) )
+        err(1, "xc_get_featureset()");
+}
+
+static void dump_info(xc_interface *xch, bool detail)
+{
+    unsigned int i;
+
+    printf("nr_features: %u\n", nr_features);
+
+    if ( !detail )
+    {
+        printf("       %"COL_ALIGN"s ", "KEY");
+        for ( i = 0; i < ARRAY_SIZE(decodes); ++i )
+            printf("%-8s ", decodes[i].abbr ?: "???");
+        printf("\n");
+    }
+
+    printf("\nStatic sets:\n");
+    decode_featureset(known_features, ARRAY_SIZE(known_features),
+                      "Known", detail);
+    decode_featureset(inverted_features, ARRAY_SIZE(inverted_features),
+                      "Inverted", detail);
+    decode_featureset(pv_featuremask, ARRAY_SIZE(pv_featuremask),
+                      "PV Mask", detail);
+    decode_featureset(hvm_shadow_featuremask, ARRAY_SIZE(hvm_shadow_featuremask),
+                      "HVM Shadow Mask", detail);
+    decode_featureset(hvm_hap_featuremask, ARRAY_SIZE(hvm_hap_featuremask),
+                      "HVM Hap Mask", detail);
+
+    printf("\nDynamic sets:\n");
+    for ( i = 0; i < ARRAY_SIZE(featuresets); ++i )
+    {
+        get_featureset(xch, i);
+
+        decode_featureset(featuresets[i].fs, featuresets[i].len,
+                          featuresets[i].name, detail);
+    }
+
+    for ( i = 0; i < ARRAY_SIZE(featuresets); ++i )
+        free(featuresets[i].fs);
+}
+
+int main(int argc, char **argv)
+{
+    enum { MODE_UNKNOWN, MODE_INFO, MODE_DETAIL, MODE_INTERPRET }
+    mode = MODE_UNKNOWN;
+
+    for ( ;; )
+    {
+        int option_index = 0, c;
+        static struct option long_options[] =
+        {
+            { "help", no_argument, NULL, 'h' },
+            { "info", no_argument, NULL, 'i' },
+            { "detail", no_argument, NULL, 'd' },
+            { "verbose", no_argument, NULL, 'v' },
+            { NULL, 0, NULL, 0 },
+        };
+
+        c = getopt_long(argc, argv, "hidv", long_options, &option_index);
+
+        if ( c == -1 )
+            break;
+
+        switch ( c )
+        {
+        case 'h':
+ option_error:
+            printf("Usage: %s [ info | detail | <featureset>* ]\n", argv[0]);
+            return 0;
+
+        case 'i':
+            mode = MODE_INFO;
+            break;
+
+        case 'd':
+        case 'v':
+            mode = MODE_DETAIL;
+            break;
+
+        default:
+            printf("Bad option '%c'\n", c);
+            goto option_error;
+        }
+    }
+
+    if ( mode == MODE_UNKNOWN )
+    {
+        if ( optind == argc )
+            mode = MODE_INFO;
+        else if ( optind < argc )
+        {
+            if ( !strcmp(argv[optind], "info") )
+            {
+                mode = MODE_INFO;
+                optind++;
+            }
+            else if ( !strcmp(argv[optind], "detail") )
+            {
+                mode = MODE_DETAIL;
+                optind++;
+            }
+            else
+                mode = MODE_INTERPRET;
+        }
+        else
+            mode = MODE_INTERPRET;
+    }
+
+    if ( mode == MODE_INFO || mode == MODE_DETAIL )
+    {
+        xc_interface *xch = xc_interface_open(0, 0, 0);
+
+        if ( !xch )
+            err(1, "xc_interface_open");
+
+        if ( xc_get_featureset(xch, 0, &nr_features, NULL) )
+            err(1, "xc_get_featureset(, NULL)");
+
+        dump_info(xch, mode == MODE_DETAIL);
+
+        xc_interface_close(xch);
+    }
+    else
+    {
+        uint32_t fs[nr_features + 1];
+
+        while ( optind < argc )
+        {
+            char *ptr = argv[optind++];
+            unsigned int i = 0;
+            int offset;
+
+            memset(fs, 0, sizeof(fs));
+
+            while ( sscanf(ptr, "%x%n", &fs[i], &offset) == 1 )
+            {
+                i++;
+                ptr += offset;
+
+                if ( i == nr_features )
+                    break;
+
+                if ( *ptr == ':' )
+                {
+                    ptr++; continue;
+                }
+                break;
+            }
+
+            decode_featureset(fs, i, "Raw", true);
+        }
+    }
+
+    return 0;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/x86/cpuid/cpuid-private.h b/xen/arch/x86/cpuid/cpuid-private.h
index 014ec43..1c92ee4 100644
--- a/xen/arch/x86/cpuid/cpuid-private.h
+++ b/xen/arch/x86/cpuid/cpuid-private.h
@@ -6,7 +6,14 @@
 
 #else
 
-# error TODO for userspace
+#include "xc_private.h"
+#include "xc_bitops.h"
+
+#include <xen/arch-x86/featureset.h>
+
+#define cpufeat_word(idx)	((idx) / 32)
+#define cpufeat_bit(idx)	((idx) % 32)
+#define cpufeat_mask(idx)	(1U << cpufeat_bit(idx))
 
 #endif
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 13/31] tools/libxc: Wire a featureset through to cpuid policy logic
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (11 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 12/31] tools: Utility for dealing with featuresets Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2016-01-05 15:42   ` Ian Campbell
  2015-12-16 21:24 ` [PATCH RFC 14/31] tools/libxc: Use featureset rather than guesswork Andrew Cooper
                   ` (17 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Ian Jackson, Ian Campbell, Wei Liu

Later changes will cause the cpuid generation logic to seed their information
from a featureset.  This patch adds the infrastructure to specify a
featureset, and will obtain the appropriate default from Xen if omitted.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Ian Campbell <Ian.Campbell@citrix.com>
CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
CC: Wei Liu <wei.liu2@citrix.com>
---
 tools/libxc/include/xenctrl.h |  3 ++
 tools/libxc/xc_cpuid_x86.c    | 90 ++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 84 insertions(+), 9 deletions(-)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 27e1f45..b44aec7 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -2211,6 +2211,9 @@ int xc_cpuid_set(xc_interface *xch,
                  char **config_transformed);
 int xc_cpuid_apply_policy(xc_interface *xch,
                           domid_t domid);
+int xc_cpuid_apply_policy_with_featureset(xc_interface *xch, domid_t domid,
+                                          uint32_t *featureset,
+                                          unsigned int nr_features);
 void xc_cpuid_to_str(const unsigned int *regs,
                      char **strs); /* some strs[] may be NULL if ENOMEM */
 int xc_mca_op(xc_interface *xch, struct xen_mc *mc);
diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
index 0a806cb..8bd3126 100644
--- a/tools/libxc/xc_cpuid_x86.c
+++ b/tools/libxc/xc_cpuid_x86.c
@@ -46,6 +46,9 @@ struct cpuid_domain_info
     bool pvh;
     uint64_t xfeature_mask;
 
+    uint32_t *featureset;
+    unsigned int nr_features;
+
     /* PV-only information. */
     bool pv64;
 
@@ -77,11 +80,14 @@ static void cpuid(const unsigned int *input, unsigned int *regs)
 }
 
 static int get_cpuid_domain_info(xc_interface *xch, domid_t domid,
-                                 struct cpuid_domain_info *info)
+                                 struct cpuid_domain_info *info,
+                                 uint32_t *featureset,
+                                 unsigned int nr_features)
 {
     struct xen_domctl domctl = {};
     xc_dominfo_t di;
     unsigned int in[2] = { 0, ~0U }, regs[4];
+    unsigned int i, host_nr_features = 0;
     int rc;
 
     cpuid(in, regs);
@@ -103,6 +109,32 @@ static int get_cpuid_domain_info(xc_interface *xch, domid_t domid,
     info->hvm = di.hvm;
     info->pvh = di.pvh;
 
+    /* Get featureset information. */
+    rc = xc_get_featureset(xch, XEN_SYSCTL_featureset_host,
+                           &host_nr_features, NULL);
+    if ( rc )
+        return rc;
+
+    if ( host_nr_features < XEN_FEATURESET_7c0 )
+        return -EINVAL;
+
+    info->featureset = calloc(host_nr_features, sizeof(*info->featureset));
+    if ( !info->featureset )
+        return -ENOMEM;
+
+    info->nr_features = host_nr_features;
+
+    if ( featureset )
+    {
+        memcpy(info->featureset, featureset,
+               min(host_nr_features, nr_features) * sizeof(*info->featureset));
+
+        /* Check for trucated set bits. */
+        for ( i = nr_features; i < host_nr_features; ++i )
+            if ( featureset[i] != 0 )
+                return -EOPNOTSUPP;
+    }
+
     /* Get xstate information. */
     domctl.cmd = XEN_DOMCTL_getvcpuextstate;
     domctl.domain = domid;
@@ -127,6 +159,14 @@ static int get_cpuid_domain_info(xc_interface *xch, domid_t domid,
             return rc;
 
         info->nestedhvm = !!val;
+
+        if ( !featureset )
+        {
+            rc = xc_get_featureset(xch, XEN_SYSCTL_featureset_hvm,
+                                   &host_nr_features, info->featureset);
+            if ( rc )
+                return rc;
+        }
     }
     else
     {
@@ -137,11 +177,24 @@ static int get_cpuid_domain_info(xc_interface *xch, domid_t domid,
             return rc;
 
         info->pv64 = (width == 8);
+
+        if ( !featureset )
+        {
+            rc = xc_get_featureset(xch, XEN_SYSCTL_featureset_pv,
+                                   &host_nr_features, info->featureset);
+            if ( rc )
+                return rc;
+        }
     }
 
     return 0;
 }
 
+static void free_cpuid_domain_info(struct cpuid_domain_info *info)
+{
+    free(info->featureset);
+}
+
 static void amd_xc_cpuid_policy(xc_interface *xch,
                                 const struct cpuid_domain_info *info,
                                 const unsigned int *input, unsigned int *regs)
@@ -653,16 +706,18 @@ void xc_cpuid_to_str(const unsigned int *regs, char **strs)
     }
 }
 
-int xc_cpuid_apply_policy(xc_interface *xch, domid_t domid)
+static int __xc_cpuid_apply_policy(xc_interface *xch, domid_t domid,
+                                   uint32_t *featureset,
+                                   unsigned int nr_features)
 {
     struct cpuid_domain_info info = {};
     unsigned int input[2] = { 0, 0 }, regs[4];
     unsigned int base_max, ext_max;
     int rc;
 
-    rc = get_cpuid_domain_info(xch, domid, &info);
+    rc = get_cpuid_domain_info(xch, domid, &info, featureset, nr_features);
     if ( rc )
-        return rc;
+        goto out;
 
     cpuid(input, regs);
     base_max = (regs[0] <= DEF_MAX_BASE) ? regs[0] : DEF_MAX_BASE;
@@ -685,7 +740,7 @@ int xc_cpuid_apply_policy(xc_interface *xch, domid_t domid)
         {
             rc = xc_cpuid_do_domctl(xch, domid, input, regs);
             if ( rc )
-                return rc;
+                goto out;
         }
 
         /* Intel cache descriptor leaves. */
@@ -713,7 +768,21 @@ int xc_cpuid_apply_policy(xc_interface *xch, domid_t domid)
             break;
     }
 
-    return 0;
+ out:
+    free_cpuid_domain_info(&info);
+    return rc;
+}
+
+int xc_cpuid_apply_policy(xc_interface *xch, domid_t domid)
+{
+    return __xc_cpuid_apply_policy(xch, domid, NULL, 0);
+}
+
+int xc_cpuid_apply_policy_with_featureset(xc_interface *xch, domid_t domid,
+                                          uint32_t *featureset,
+                                          unsigned int nr_features)
+{
+    return __xc_cpuid_apply_policy(xch, domid, featureset, nr_features);
 }
 
 /*
@@ -802,9 +871,9 @@ int xc_cpuid_set(
 
     memset(config_transformed, 0, 4 * sizeof(*config_transformed));
 
-    rc = get_cpuid_domain_info(xch, domid, &info);
+    rc = get_cpuid_domain_info(xch, domid, &info, NULL, 0);
     if ( rc )
-        return rc;
+        goto out;
 
     cpuid(input, regs);
 
@@ -855,7 +924,7 @@ int xc_cpuid_set(
 
     rc = xc_cpuid_do_domctl(xch, domid, input, regs);
     if ( rc == 0 )
-        return 0;
+        goto out;
 
  fail:
     for ( i = 0; i < 4; i++ )
@@ -863,5 +932,8 @@ int xc_cpuid_set(
         free(config_transformed[i]);
         config_transformed[i] = NULL;
     }
+
+ out:
+    free_cpuid_domain_info(&info);
     return rc;
 }
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 14/31] tools/libxc: Use featureset rather than guesswork
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (12 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 13/31] tools/libxc: Wire a featureset through to cpuid policy logic Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2016-01-05 15:54   ` Ian Campbell
  2015-12-16 21:24 ` [PATCH RFC 15/31] x86: Generate deep dependencies of x86 features Andrew Cooper
                   ` (16 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Ian Jackson, Ian Campbell, Wei Liu

It is conceptually wrong to base a VM's featureset on the features visible to
the toolstack which happens to construct it.

Instead, the featureset used is either an explicit one passed by the
toolstack, or the default which Xen believes it can give to the guest.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Ian Campbell <Ian.Campbell@citrix.com>
CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
CC: Wei Liu <wei.liu2@citrix.com>
---
 tools/libxc/xc_cpuid_x86.c | 229 +++++++++++++--------------------------------
 1 file changed, 64 insertions(+), 165 deletions(-)

diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
index 8bd3126..3f39306 100644
--- a/tools/libxc/xc_cpuid_x86.c
+++ b/tools/libxc/xc_cpuid_x86.c
@@ -24,6 +24,7 @@
 #include "xc_private.h"
 #include <xen/arch-x86/featureset.h>
 #include <xen/hvm/params.h>
+#include <xen/sysctl.h>
 
 #define bitmaskof(idx)      (1u << ((idx) & 31))
 #define clear_bit(idx, dst) ((dst) &= ~bitmaskof(idx))
@@ -211,37 +212,19 @@ static void amd_xc_cpuid_policy(xc_interface *xch,
             regs[0] = DEF_MAX_AMDEXT;
         break;
 
-    case 0x80000001: {
+    case 0x80000001:
         if ( !info->pae )
             clear_bit(X86_FEATURE_PAE, regs[3]);
 
-        /* Filter all other features according to a whitelist. */
-        regs[2] &= (bitmaskof(X86_FEATURE_LAHF_LM) |
-                    bitmaskof(X86_FEATURE_CMP_LEGACY) |
-                    (info->nestedhvm ? bitmaskof(X86_FEATURE_SVM) : 0) |
-                    bitmaskof(X86_FEATURE_CR8_LEGACY) |
-                    bitmaskof(X86_FEATURE_ABM) |
-                    bitmaskof(X86_FEATURE_SSE4A) |
-                    bitmaskof(X86_FEATURE_MISALIGNSSE) |
-                    bitmaskof(X86_FEATURE_3DNOWPREFETCH) |
-                    bitmaskof(X86_FEATURE_OSVW) |
-                    bitmaskof(X86_FEATURE_XOP) |
-                    bitmaskof(X86_FEATURE_LWP) |
-                    bitmaskof(X86_FEATURE_FMA4) |
-                    bitmaskof(X86_FEATURE_TBM) |
-                    bitmaskof(X86_FEATURE_DBEXT));
-        regs[3] &= (0x0183f3ff | /* features shared with 0x00000001:EDX */
-                    bitmaskof(X86_FEATURE_NX) |
-                    bitmaskof(X86_FEATURE_LM) |
-                    bitmaskof(X86_FEATURE_PAGE1GB) |
-                    bitmaskof(X86_FEATURE_SYSCALL) |
-                    bitmaskof(X86_FEATURE_MP) |
-                    bitmaskof(X86_FEATURE_MMXEXT) |
-                    bitmaskof(X86_FEATURE_FFXSR) |
-                    bitmaskof(X86_FEATURE_3DNOW) |
-                    bitmaskof(X86_FEATURE_3DNOWEXT));
+        if ( !info->nestedhvm )
+            clear_bit(X86_FEATURE_SVM, regs[2]);
+
+        if ( info->xfeature_mask == 0 )
+        {
+            clear_bit(X86_FEATURE_FMA4, regs[2]);
+            clear_bit(X86_FEATURE_LWP, regs[2]);
+        }
         break;
-    }
 
     case 0x80000008:
         /*
@@ -290,9 +273,8 @@ static void intel_xc_cpuid_policy(xc_interface *xch,
     switch ( input[0] )
     {
     case 0x00000001:
-        /* ECX[5] is availability of VMX */
-        if ( info->nestedhvm )
-            set_bit(X86_FEATURE_VMXE, regs[2]);
+        if ( !info->nestedhvm )
+            clear_bit(X86_FEATURE_VMXE, regs[2]);
         break;
 
     case 0x00000004:
@@ -310,19 +292,6 @@ static void intel_xc_cpuid_policy(xc_interface *xch,
             regs[0] = DEF_MAX_INTELEXT;
         break;
 
-    case 0x80000001: {
-        /* Only a few features are advertised in Intel's 0x80000001. */
-        regs[2] &= (bitmaskof(X86_FEATURE_LAHF_LM) |
-                    bitmaskof(X86_FEATURE_3DNOWPREFETCH) |
-                    bitmaskof(X86_FEATURE_ABM));
-        regs[3] &= (bitmaskof(X86_FEATURE_NX) |
-                    bitmaskof(X86_FEATURE_LM) |
-                    bitmaskof(X86_FEATURE_PAGE1GB) |
-                    bitmaskof(X86_FEATURE_SYSCALL) |
-                    bitmaskof(X86_FEATURE_RDTSCP));
-        break;
-    }
-
     case 0x80000005:
         regs[0] = regs[1] = regs[2] = 0;
         break;
@@ -371,7 +340,7 @@ static void xc_cpuid_config_xsave(xc_interface *xch,
         regs[1] = 512 + 64; /* FP/SSE + XSAVE.HEADER */
         break;
     case 1: /* leaf 1 */
-        regs[0] &= XSAVEOPT;
+        regs[0] = info->featureset[XEN_FEATURESET_Da1];
         regs[1] = regs[2] = regs[3] = 0;
         break;
     case 2 ... 63: /* sub-leaves */
@@ -404,53 +373,16 @@ static void xc_cpuid_hvm_policy(xc_interface *xch,
          */
         regs[1] = (regs[1] & 0x0000ffffu) | ((regs[1] & 0x007f0000u) << 1);
 
-        regs[2] &= (bitmaskof(X86_FEATURE_XMM3) |
-                    bitmaskof(X86_FEATURE_PCLMULQDQ) |
-                    bitmaskof(X86_FEATURE_SSSE3) |
-                    bitmaskof(X86_FEATURE_FMA) |
-                    bitmaskof(X86_FEATURE_CX16) |
-                    bitmaskof(X86_FEATURE_PCID) |
-                    bitmaskof(X86_FEATURE_SSE4_1) |
-                    bitmaskof(X86_FEATURE_SSE4_2) |
-                    bitmaskof(X86_FEATURE_MOVBE)  |
-                    bitmaskof(X86_FEATURE_POPCNT) |
-                    bitmaskof(X86_FEATURE_AES) |
-                    bitmaskof(X86_FEATURE_F16C) |
-                    bitmaskof(X86_FEATURE_RDRAND) |
-                    ((info->xfeature_mask != 0) ?
-                     (bitmaskof(X86_FEATURE_AVX) |
-                      bitmaskof(X86_FEATURE_XSAVE)) : 0));
-
-        regs[2] |= (bitmaskof(X86_FEATURE_HYPERVISOR) |
-                    bitmaskof(X86_FEATURE_TSC_DEADLINE) |
-                    bitmaskof(X86_FEATURE_X2APIC));
-
-        regs[3] &= (bitmaskof(X86_FEATURE_FPU) |
-                    bitmaskof(X86_FEATURE_VME) |
-                    bitmaskof(X86_FEATURE_DE) |
-                    bitmaskof(X86_FEATURE_PSE) |
-                    bitmaskof(X86_FEATURE_TSC) |
-                    bitmaskof(X86_FEATURE_MSR) |
-                    bitmaskof(X86_FEATURE_PAE) |
-                    bitmaskof(X86_FEATURE_MCE) |
-                    bitmaskof(X86_FEATURE_CX8) |
-                    bitmaskof(X86_FEATURE_APIC) |
-                    bitmaskof(X86_FEATURE_SEP) |
-                    bitmaskof(X86_FEATURE_MTRR) |
-                    bitmaskof(X86_FEATURE_PGE) |
-                    bitmaskof(X86_FEATURE_MCA) |
-                    bitmaskof(X86_FEATURE_CMOV) |
-                    bitmaskof(X86_FEATURE_PAT) |
-                    bitmaskof(X86_FEATURE_CLFLSH) |
-                    bitmaskof(X86_FEATURE_PSE36) |
-                    bitmaskof(X86_FEATURE_MMX) |
-                    bitmaskof(X86_FEATURE_FXSR) |
-                    bitmaskof(X86_FEATURE_XMM) |
-                    bitmaskof(X86_FEATURE_XMM2) |
-                    bitmaskof(X86_FEATURE_HT));
-            
-        /* We always support MTRR MSRs. */
-        regs[3] |= bitmaskof(X86_FEATURE_MTRR);
+        regs[2] = info->featureset[XEN_FEATURESET_1c];
+        regs[3] = info->featureset[XEN_FEATURESET_1d];
+
+        if ( info->xfeature_mask == 0 )
+        {
+            clear_bit(X86_FEATURE_AVX, regs[2]);
+            clear_bit(X86_FEATURE_F16C, regs[2]);
+            clear_bit(X86_FEATURE_FMA, regs[2]);
+            clear_bit(X86_FEATURE_XSAVE, regs[2]);
+        }
 
         if ( !info->pae )
         {
@@ -460,23 +392,17 @@ static void xc_cpuid_hvm_policy(xc_interface *xch,
         break;
 
     case 0x00000007: /* Intel-defined CPU features */
-        if ( input[1] == 0 ) {
-            regs[1] &= (bitmaskof(X86_FEATURE_TSC_ADJUST) |
-                        bitmaskof(X86_FEATURE_BMI1) |
-                        bitmaskof(X86_FEATURE_HLE)  |
-                        bitmaskof(X86_FEATURE_AVX2) |
-                        bitmaskof(X86_FEATURE_SMEP) |
-                        bitmaskof(X86_FEATURE_BMI2) |
-                        bitmaskof(X86_FEATURE_ERMS) |
-                        bitmaskof(X86_FEATURE_INVPCID) |
-                        bitmaskof(X86_FEATURE_RTM)  |
-                        bitmaskof(X86_FEATURE_RDSEED)  |
-                        bitmaskof(X86_FEATURE_ADX)  |
-                        bitmaskof(X86_FEATURE_SMAP) |
-                        bitmaskof(X86_FEATURE_FSGSBASE));
-        } else
+        if ( input[1] == 0 )
+        {
+            regs[1] = info->featureset[XEN_FEATURESET_7b0];
+            regs[2] = info->featureset[XEN_FEATURESET_7c0];
+        }
+        else
+        {
             regs[1] = 0;
-        regs[0] = regs[2] = regs[3] = 0;
+            regs[2] = 0;
+        }
+        regs[0] = regs[3] = 0;
         break;
 
     case 0x0000000d:
@@ -488,6 +414,9 @@ static void xc_cpuid_hvm_policy(xc_interface *xch,
         break;
 
     case 0x80000001:
+        regs[2] = info->featureset[XEN_FEATURESET_e1c];
+        regs[3] = info->featureset[XEN_FEATURESET_e1d];
+
         if ( !info->pae )
         {
             clear_bit(X86_FEATURE_LAHF_LM, regs[2]);
@@ -539,64 +468,42 @@ static void xc_cpuid_pv_policy(xc_interface *xch,
                                const struct cpuid_domain_info *info,
                                const unsigned int *input, unsigned int *regs)
 {
-    if ( (input[0] & 0x7fffffff) == 0x00000001 )
-    {
-        clear_bit(X86_FEATURE_VME, regs[3]);
-        if ( !info->pvh )
-        {
-            clear_bit(X86_FEATURE_PSE, regs[3]);
-            clear_bit(X86_FEATURE_PGE, regs[3]);
-        }
-        clear_bit(X86_FEATURE_MCE, regs[3]);
-        clear_bit(X86_FEATURE_MCA, regs[3]);
-        clear_bit(X86_FEATURE_MTRR, regs[3]);
-        clear_bit(X86_FEATURE_PSE36, regs[3]);
-    }
-
     switch ( input[0] )
     {
     case 0x00000001:
-        if ( info->vendor == VENDOR_AMD )
-            clear_bit(X86_FEATURE_SEP, regs[3]);
-        clear_bit(X86_FEATURE_DS, regs[3]);
-        clear_bit(X86_FEATURE_ACC, regs[3]);
-        clear_bit(X86_FEATURE_PBE, regs[3]);
-
-        clear_bit(X86_FEATURE_DTES64, regs[2]);
-        clear_bit(X86_FEATURE_MWAIT, regs[2]);
-        clear_bit(X86_FEATURE_DSCPL, regs[2]);
-        clear_bit(X86_FEATURE_VMXE, regs[2]);
-        clear_bit(X86_FEATURE_SMXE, regs[2]);
-        clear_bit(X86_FEATURE_EST, regs[2]);
-        clear_bit(X86_FEATURE_TM2, regs[2]);
+        regs[2] = info->featureset[XEN_FEATURESET_1c];
+        regs[3] = info->featureset[XEN_FEATURESET_1d];
+
         if ( !info->pv64 )
             clear_bit(X86_FEATURE_CX16, regs[2]);
+
         if ( info->xfeature_mask == 0 )
         {
             clear_bit(X86_FEATURE_XSAVE, regs[2]);
             clear_bit(X86_FEATURE_AVX, regs[2]);
+            clear_bit(X86_FEATURE_F16C, regs[2]);
+            clear_bit(X86_FEATURE_FMA, regs[2]);
+        }
+
+        if ( !info->pvh )
+        {
+            clear_bit(X86_FEATURE_PSE, regs[3]);
+            clear_bit(X86_FEATURE_PGE, regs[3]);
         }
-        clear_bit(X86_FEATURE_XTPR, regs[2]);
-        clear_bit(X86_FEATURE_PDCM, regs[2]);
-        clear_bit(X86_FEATURE_PCID, regs[2]);
-        clear_bit(X86_FEATURE_DCA, regs[2]);
-        set_bit(X86_FEATURE_HYPERVISOR, regs[2]);
         break;
 
     case 0x00000007:
         if ( input[1] == 0 )
-            regs[1] &= (bitmaskof(X86_FEATURE_BMI1) |
-                        bitmaskof(X86_FEATURE_HLE)  |
-                        bitmaskof(X86_FEATURE_AVX2) |
-                        bitmaskof(X86_FEATURE_BMI2) |
-                        bitmaskof(X86_FEATURE_ERMS) |
-                        bitmaskof(X86_FEATURE_RTM)  |
-                        bitmaskof(X86_FEATURE_RDSEED)  |
-                        bitmaskof(X86_FEATURE_ADX)  |
-                        bitmaskof(X86_FEATURE_FSGSBASE));
+        {
+            regs[1] = info->featureset[XEN_FEATURESET_7b0];
+            regs[2] = info->featureset[XEN_FEATURESET_7c0];
+        }
         else
+        {
             regs[1] = 0;
-        regs[0] = regs[2] = regs[3] = 0;
+            regs[2] = 0;
+        }
+        regs[0] = regs[3] = 0;
         break;
 
     case 0x0000000d:
@@ -604,29 +511,21 @@ static void xc_cpuid_pv_policy(xc_interface *xch,
         break;
 
     case 0x80000001:
+        regs[2] = info->featureset[XEN_FEATURESET_e1c];
+        regs[3] = info->featureset[XEN_FEATURESET_e1d];
+
         if ( !info->pv64 )
         {
             clear_bit(X86_FEATURE_LM, regs[3]);
             clear_bit(X86_FEATURE_LAHF_LM, regs[2]);
-            if ( info->vendor != VENDOR_AMD )
-                clear_bit(X86_FEATURE_SYSCALL, regs[3]);
-        }
-        else
-        {
-            set_bit(X86_FEATURE_SYSCALL, regs[3]);
         }
+
         if ( !info->pvh )
+        {
+            clear_bit(X86_FEATURE_PSE, regs[3]);
+            clear_bit(X86_FEATURE_PGE, regs[3]);
             clear_bit(X86_FEATURE_PAGE1GB, regs[3]);
-        clear_bit(X86_FEATURE_RDTSCP, regs[3]);
-
-        clear_bit(X86_FEATURE_SVM, regs[2]);
-        clear_bit(X86_FEATURE_OSVW, regs[2]);
-        clear_bit(X86_FEATURE_IBS, regs[2]);
-        clear_bit(X86_FEATURE_SKINIT, regs[2]);
-        clear_bit(X86_FEATURE_WDT, regs[2]);
-        clear_bit(X86_FEATURE_LWP, regs[2]);
-        clear_bit(X86_FEATURE_NODEID_MSR, regs[2]);
-        clear_bit(X86_FEATURE_TOPOEXT, regs[2]);
+        }
         break;
 
     case 0x00000005: /* MONITOR/MWAIT */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 15/31] x86: Generate deep dependencies of x86 features
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (13 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 14/31] tools/libxc: Use featureset rather than guesswork Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2016-01-05 16:03   ` Ian Campbell
  2015-12-16 21:24 ` [PATCH RFC 16/31] x86: Automatically generate known_features Andrew Cooper
                   ` (15 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Ian Jackson, Ian Campbell, Jan Beulich, Wei Liu

Some features depend on other features.  Working out and maintaining the exact
dependency tree is complicated, so it is expressed in script form instead.

`gen-feature-deps.py` parses 'xen/include/public/arch-x86/featureset.h' (To
obtain some literal names conforming to the API), contains some single-step
dependency information, performs some number crunching, and writes autogen.c
to make the results of the number crunching available.

In this case, it writes out deep dependency infomarion, to allow featureset
code to find all eventual features cleared in a dependency chain.

To be able to compile for userspace, libxc's bitmap macros are made more
generic (to match Xen's), and accept a void * instead of unsigned long *.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Ian Campbell <Ian.Campbell@citrix.com>
CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
CC: Wei Liu <wei.liu2@citrix.com>

TODO: The generation of autogen.c now means that libxc needs to be compiled
after the hypervisor, as the vpath doesn't convey the generation information.
I need to find a way to fix this.
---
 .gitignore                             |   1 +
 tools/libxc/Makefile                   |   2 +-
 tools/libxc/xc_bitops.h                |  12 +--
 xen/arch/x86/cpuid/Makefile            |   5 ++
 xen/arch/x86/cpuid/cpuid-private.h     |  18 ++++
 xen/arch/x86/cpuid/cpuid.c             |  28 ++++++
 xen/arch/x86/cpuid/gen-feature-deps.py | 152 +++++++++++++++++++++++++++++++++
 7 files changed, 211 insertions(+), 7 deletions(-)
 create mode 100755 xen/arch/x86/cpuid/gen-feature-deps.py

diff --git a/.gitignore b/.gitignore
index 63944b5..f757164 100644
--- a/.gitignore
+++ b/.gitignore
@@ -228,6 +228,7 @@ xen/arch/x86/xen.lds
 xen/arch/x86/boot/reloc.S
 xen/arch/x86/boot/reloc.bin
 xen/arch/x86/boot/reloc.lnk
+xen/arch/x86/cpuid/autogen.c
 xen/arch/x86/efi.lds
 xen/arch/x86/efi/check.efi
 xen/arch/x86/efi/disabled
diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
index 83547e1..7c8c2d8 100644
--- a/tools/libxc/Makefile
+++ b/tools/libxc/Makefile
@@ -82,7 +82,7 @@ $(patsubst %.c,%.opic,$(ELF_SRCS-y)): CFLAGS += -Wno-pointer-sign
 ifeq ($(CONFIG_X86),y)
 vpath %.c ../../xen/arch/x86/cpuid
 CFLAGS += -I../../xen/arch/x86/cpuid
-CTRL_SRCS-y += cpuid.c
+CTRL_SRCS-y += cpuid.c autogen.c
 endif
 
 # new domain builder
diff --git a/tools/libxc/xc_bitops.h b/tools/libxc/xc_bitops.h
index cd749f4..8e645a1 100644
--- a/tools/libxc/xc_bitops.h
+++ b/tools/libxc/xc_bitops.h
@@ -36,19 +36,19 @@ static inline void bitmap_clear(unsigned long *addr, int nr_bits)
     memset(addr, 0, bitmap_size(nr_bits));
 }
 
-static inline int test_bit(int nr, unsigned long *addr)
+static inline int test_bit(int nr, const void *addr)
 {
-    return (BITMAP_ENTRY(nr, addr) >> BITMAP_SHIFT(nr)) & 1;
+    return (BITMAP_ENTRY(nr, (const unsigned long *)addr) >> BITMAP_SHIFT(nr)) & 1;
 }
 
-static inline void clear_bit(int nr, unsigned long *addr)
+static inline void clear_bit(int nr, void *addr)
 {
-    BITMAP_ENTRY(nr, addr) &= ~(1UL << BITMAP_SHIFT(nr));
+    BITMAP_ENTRY(nr, (unsigned long *)addr) &= ~(1UL << BITMAP_SHIFT(nr));
 }
 
-static inline void set_bit(int nr, unsigned long *addr)
+static inline void set_bit(int nr, void *addr)
 {
-    BITMAP_ENTRY(nr, addr) |= (1UL << BITMAP_SHIFT(nr));
+    BITMAP_ENTRY(nr, (unsigned long *)addr) |= (1UL << BITMAP_SHIFT(nr));
 }
 
 static inline int test_and_clear_bit(int nr, unsigned long *addr)
diff --git a/xen/arch/x86/cpuid/Makefile b/xen/arch/x86/cpuid/Makefile
index 3fb2e0b..0fb720a 100644
--- a/xen/arch/x86/cpuid/Makefile
+++ b/xen/arch/x86/cpuid/Makefile
@@ -1 +1,6 @@
 obj-y += cpuid.o
+obj-y += autogen.o
+
+autogen.c: gen-feature-deps.py
+	$(PYTHON) gen-feature-deps.py
+	$(call move-if-changed,autogen.c.tmp,autogen.c)
diff --git a/xen/arch/x86/cpuid/cpuid-private.h b/xen/arch/x86/cpuid/cpuid-private.h
index 1c92ee4..438f5d2 100644
--- a/xen/arch/x86/cpuid/cpuid-private.h
+++ b/xen/arch/x86/cpuid/cpuid-private.h
@@ -64,6 +64,24 @@ extern const uint32_t pv_featuremask[XEN_NR_FEATURESET_ENTRIES];
 extern const uint32_t hvm_shadow_featuremask[XEN_NR_FEATURESET_ENTRIES];
 extern const uint32_t hvm_hap_featuremask[XEN_NR_FEATURESET_ENTRIES];
 
+/* A featureset with a tag. */
+struct tagged_featureset
+{
+    uint32_t tag;
+    uint32_t fs[XEN_NR_FEATURESET_ENTRIES];
+};
+
+/* Sparse feature matrix identifying all features which depend on a feature. */
+extern const struct tagged_featureset deep_deps[];
+
+/* Number of entries in deep_deps. */
+extern const unsigned int nr_deep_deps;
+
+/* Bitmap of each tag found in 'deep_deps'. */
+extern const uint32_t deep_dep_features[XEN_NR_FEATURESET_ENTRIES];
+
+const struct tagged_featureset *lookup_deep_deps(uint32_t feature);
+
 /*
  * Local variables:
  * mode: C
diff --git a/xen/arch/x86/cpuid/cpuid.c b/xen/arch/x86/cpuid/cpuid.c
index 25385d4..20c36f7 100644
--- a/xen/arch/x86/cpuid/cpuid.c
+++ b/xen/arch/x86/cpuid/cpuid.c
@@ -300,6 +300,34 @@ const uint32_t hvm_hap_featuremask[XEN_NR_FEATURESET_ENTRIES] =
 };
 
 /*
+ * Looks up a features deep dependency.  Returns a pointer, or NULL if not
+ * found.
+ */
+const struct tagged_featureset *lookup_deep_deps(uint32_t feat)
+{
+    unsigned int start = 0, end = nr_deep_deps;
+
+    /* Fast early exit. */
+    if ( !test_bit(feat, deep_dep_features) )
+        return NULL;
+
+    /* deep_deps[] is sorted.  Perform a binary search. */
+    while ( start < end )
+    {
+        unsigned int mid = start + ((end - start) / 2);
+
+        if ( deep_deps[mid].tag > feat )
+            end = mid;
+        else if ( deep_deps[mid].tag < feat )
+            start = mid + 1;
+        else
+            return &deep_deps[mid];
+    }
+
+    return NULL;
+}
+
+/*
  * Local variables:
  * mode: C
  * c-file-style: "BSD"
diff --git a/xen/arch/x86/cpuid/gen-feature-deps.py b/xen/arch/x86/cpuid/gen-feature-deps.py
new file mode 100755
index 0000000..f0ecbba
--- /dev/null
+++ b/xen/arch/x86/cpuid/gen-feature-deps.py
@@ -0,0 +1,152 @@
+#!/usr/bin/env python
+import sys, os, os.path as path, re
+
+names = {}
+
+with open(path.join(os.environ["XEN_ROOT"],
+                    "xen/include/public/arch-x86/featureset.h")) as f:
+
+    feat_regex = re.compile(
+        r"^#define X86_FEATURE_([A-Z0-9_]+)"
+        "\s+\(([\s\d]+\*[\s\d]+\+[\s\d]+)\)")
+
+    this = sys.modules[__name__]
+
+    for l in f.readlines():
+        # Short circuit the regex...
+        if not l.startswith("#define X86_FEATURE_"):
+            continue
+
+        res = feat_regex.match(l)
+
+        if res is None:
+            print >>sys.stderr, "Failed to interpret '%s'" % (l, )
+            sys.exit(1)
+
+        name = res.groups()[0]
+        val = eval(res.groups()[1]) # Regex confines this to a very simple expression
+
+        # Expected duplicate symbols.  Discard
+        if name in ('3DNOW_ALT', ):
+            continue
+
+        if hasattr(this, name) or val in names:
+            print >>sys.stderr, "Duplicate symbol or representation for '%s'" \
+                % (name, )
+            sys.exit(1)
+
+        # Mutate the current namespace to insert a feature literal with its
+        # bit index
+        setattr(this, name, val)
+
+        # Construct a reverse mapping of value to name
+        names[val] = name
+
+
+# Dependences specified as a dictionary of tuples: The feature in the key
+# is a direct dependency of each of the features in the tuple.
+deps = {
+    XSAVE:
+    (XSAVEOPT, XSAVEC, XGETBV1, XSAVES, AVX, MPX),
+
+    AVX:
+    (FMA, FMA4, F16C, AVX2, XOP),
+
+    PAE:
+    (LM, ),
+
+    LM:
+    (CX16, LAHF_LM, PAGE1GB),
+
+    XMM:
+    (LM, ),
+
+    XMM2:
+    (LM, ),
+
+    XMM3:
+    (LM, ),
+
+    APIC:
+    (X2APIC, ),
+
+    PSE:
+    (PSE36, ),
+}
+
+deep_features = tuple(sorted(deps.keys()))
+
+deep_deps = {}
+for feat in deep_features:
+
+    seen = [feat]
+    to_process = list(deps[feat])
+
+    while len(to_process):
+        f = to_process.pop(0)
+
+        if f in seen:
+            print >>sys.stderr, "ERROR: Cycle found with %s when processing %s" \
+                % (names[f], names[feat])
+            sys.exit(1)
+
+        seen.append(f)
+        to_process.extend(deps.get(f, []))
+
+    deep_deps[feat] = seen[1:]
+
+def format_featurset(fs):
+
+    words = {}
+    res = "\n"
+
+    # Identify which featureset words each feature resides in
+    for f in fs:
+        word = f >> 5
+
+        if word in words:
+            words[word].append(f)
+        else:
+            words[word] = [f]
+
+    for w in sorted(words.keys()):
+        wf = sorted(words[w])
+
+        res += "        [cpufeat_word(X86_FEATURE_%s)] = (\n" % (names[wf[0]], )
+
+        res += " |\n".join(
+            "            cpufeat_mask(X86_FEATURE_%s)" %
+            (names[f], ) for f in wf)
+
+        res += "),\n\n"
+
+    return res.rstrip()
+
+with open(path.join(os.environ["XEN_ROOT"],
+                    "xen/arch/x86/cpuid/autogen.c.tmp"), "w") as f:
+    f.write(
+"""/*
+ * Automatically generated by %s - Do not edit!
+ */
+#include "cpuid-private.h"
+
+const struct tagged_featureset deep_deps[] =
+{""" % (sys.argv[0],))
+
+    for d in sorted(deep_deps.keys()):
+        f.write("""
+    { X86_FEATURE_%s,
+      {%s
+      }
+    },
+""" % (names[d], format_featurset(deep_deps[d])))
+
+    f.write(
+"""};
+
+const unsigned int nr_deep_deps = ARRAY_SIZE(deep_deps);
+
+const uint32_t deep_dep_features[XEN_NR_FEATURESET_ENTRIES] =
+{%s
+};
+""" % (format_featurset(deep_features), ))
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 16/31] x86: Automatically generate known_features
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (14 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 15/31] x86: Generate deep dependencies of x86 features Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2015-12-16 21:24 ` [PATCH RFC 17/31] xen/x86: Clear dependent features when clearing a cpu cap Andrew Cooper
                   ` (14 subsequent siblings)
  30 siblings, 0 replies; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Jan Beulich

Use the new gen-feature-deps.py infrastructure to automatically generate
known_features[], rather than requiring people to patch two places to add a
new feature for hypervisor use.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>

TODO: Probably move the introduction of gen-feature-deps.py earier in the
series, so "xen/x86: Mask out unknown features from Xen's capabilities" uses
the automatically generated known_features[].
---
 xen/arch/x86/cpuid/cpuid.c             | 115 ---------------------------------
 xen/arch/x86/cpuid/gen-feature-deps.py |  23 ++++++-
 2 files changed, 20 insertions(+), 118 deletions(-)

diff --git a/xen/arch/x86/cpuid/cpuid.c b/xen/arch/x86/cpuid/cpuid.c
index 20c36f7..c1f3e22 100644
--- a/xen/arch/x86/cpuid/cpuid.c
+++ b/xen/arch/x86/cpuid/cpuid.c
@@ -1,120 +1,5 @@
 #include "cpuid-private.h"
 
-const uint32_t known_features[XEN_NR_FEATURESET_ENTRIES] =
-{
-    [cpufeat_word(X86_FEATURE_FPU)] = (SHARED_1d                           |
-                                       cpufeat_mask(X86_FEATURE_SEP)       |
-                                       cpufeat_mask(X86_FEATURE_PN)        |
-                                       cpufeat_mask(X86_FEATURE_CLFLSH)    |
-                                       cpufeat_mask(X86_FEATURE_DS)        |
-                                       cpufeat_mask(X86_FEATURE_ACPI)      |
-                                       cpufeat_mask(X86_FEATURE_XMM)       |
-                                       cpufeat_mask(X86_FEATURE_XMM2)      |
-                                       cpufeat_mask(X86_FEATURE_SELFSNOOP) |
-                                       cpufeat_mask(X86_FEATURE_HT)        |
-                                       cpufeat_mask(X86_FEATURE_ACC)       |
-                                       cpufeat_mask(X86_FEATURE_IA64)      |
-                                       cpufeat_mask(X86_FEATURE_PBE)),
-
-    [cpufeat_word(X86_FEATURE_XMM3)] = (cpufeat_mask(X86_FEATURE_XMM3)         |
-                                        cpufeat_mask(X86_FEATURE_PCLMULQDQ)    |
-                                        cpufeat_mask(X86_FEATURE_DTES64)       |
-                                        cpufeat_mask(X86_FEATURE_MWAIT)        |
-                                        cpufeat_mask(X86_FEATURE_DSCPL)        |
-                                        cpufeat_mask(X86_FEATURE_VMXE)         |
-                                        cpufeat_mask(X86_FEATURE_SMXE)         |
-                                        cpufeat_mask(X86_FEATURE_EST)          |
-                                        cpufeat_mask(X86_FEATURE_TM2)          |
-                                        cpufeat_mask(X86_FEATURE_SSSE3)        |
-                                        cpufeat_mask(X86_FEATURE_CID)          |
-                                        cpufeat_mask(X86_FEATURE_FMA)          |
-                                        cpufeat_mask(X86_FEATURE_CX16)         |
-                                        cpufeat_mask(X86_FEATURE_XTPR)         |
-                                        cpufeat_mask(X86_FEATURE_PDCM)         |
-                                        cpufeat_mask(X86_FEATURE_PCID)         |
-                                        cpufeat_mask(X86_FEATURE_DCA)          |
-                                        cpufeat_mask(X86_FEATURE_SSE4_1)       |
-                                        cpufeat_mask(X86_FEATURE_SSE4_2)       |
-                                        cpufeat_mask(X86_FEATURE_X2APIC)       |
-                                        cpufeat_mask(X86_FEATURE_MOVBE)        |
-                                        cpufeat_mask(X86_FEATURE_POPCNT)       |
-                                        cpufeat_mask(X86_FEATURE_TSC_DEADLINE) |
-                                        cpufeat_mask(X86_FEATURE_AES)          |
-                                        cpufeat_mask(X86_FEATURE_XSAVE)        |
-                                        cpufeat_mask(X86_FEATURE_OSXSAVE)      |
-                                        cpufeat_mask(X86_FEATURE_AVX)          |
-                                        cpufeat_mask(X86_FEATURE_F16C)         |
-                                        cpufeat_mask(X86_FEATURE_RDRAND)       |
-                                        cpufeat_mask(X86_FEATURE_HYPERVISOR)),
-
-    [cpufeat_word(X86_FEATURE_SYSCALL)] = (SHARED_1d                          |
-                                           cpufeat_mask(X86_FEATURE_SYSCALL)  |
-                                           cpufeat_mask(X86_FEATURE_MP)       |
-                                           cpufeat_mask(X86_FEATURE_NX)       |
-                                           cpufeat_mask(X86_FEATURE_MMXEXT)   |
-                                           cpufeat_mask(X86_FEATURE_FFXSR)    |
-                                           cpufeat_mask(X86_FEATURE_PAGE1GB)  |
-                                           cpufeat_mask(X86_FEATURE_RDTSCP)   |
-                                           cpufeat_mask(X86_FEATURE_LM)       |
-                                           cpufeat_mask(X86_FEATURE_3DNOWEXT) |
-                                           cpufeat_mask(X86_FEATURE_3DNOW)),
-
-    [cpufeat_word(X86_FEATURE_LAHF_LM)] = (cpufeat_mask(X86_FEATURE_LAHF_LM)       |
-                                           cpufeat_mask(X86_FEATURE_CMP_LEGACY)    |
-                                           cpufeat_mask(X86_FEATURE_SVM)           |
-                                           cpufeat_mask(X86_FEATURE_EXTAPIC)       |
-                                           cpufeat_mask(X86_FEATURE_CR8_LEGACY)    |
-                                           cpufeat_mask(X86_FEATURE_ABM)           |
-                                           cpufeat_mask(X86_FEATURE_SSE4A)         |
-                                           cpufeat_mask(X86_FEATURE_MISALIGNSSE)   |
-                                           cpufeat_mask(X86_FEATURE_3DNOWPREFETCH) |
-                                           cpufeat_mask(X86_FEATURE_OSVW)          |
-                                           cpufeat_mask(X86_FEATURE_IBS)           |
-                                           cpufeat_mask(X86_FEATURE_XOP)           |
-                                           cpufeat_mask(X86_FEATURE_SKINIT)        |
-                                           cpufeat_mask(X86_FEATURE_WDT)           |
-                                           cpufeat_mask(X86_FEATURE_LWP)           |
-                                           cpufeat_mask(X86_FEATURE_FMA4)          |
-                                           cpufeat_mask(X86_FEATURE_NODEID_MSR)    |
-                                           cpufeat_mask(X86_FEATURE_TBM)           |
-                                           cpufeat_mask(X86_FEATURE_TOPOEXT)       |
-                                           cpufeat_mask(X86_FEATURE_DBEXT)         |
-                                           cpufeat_mask(X86_FEATURE_MWAITX)),
-
-    [cpufeat_word(X86_FEATURE_XSAVEOPT)] = (cpufeat_mask(X86_FEATURE_XSAVEOPT) |
-                                            cpufeat_mask(X86_FEATURE_XSAVEC)   |
-                                            cpufeat_mask(X86_FEATURE_XGETBV1)  |
-                                            cpufeat_mask(X86_FEATURE_XSAVES)),
-
-    [cpufeat_word(X86_FEATURE_FSGSBASE)] = (cpufeat_mask(X86_FEATURE_FSGSBASE)   |
-                                            cpufeat_mask(X86_FEATURE_TSC_ADJUST) |
-                                            cpufeat_mask(X86_FEATURE_BMI1)       |
-                                            cpufeat_mask(X86_FEATURE_HLE)        |
-                                            cpufeat_mask(X86_FEATURE_AVX2)       |
-                                            cpufeat_mask(X86_FEATURE_SMEP)       |
-                                            cpufeat_mask(X86_FEATURE_BMI2)       |
-                                            cpufeat_mask(X86_FEATURE_ERMS)       |
-                                            cpufeat_mask(X86_FEATURE_INVPCID)    |
-                                            cpufeat_mask(X86_FEATURE_RTM)        |
-                                            cpufeat_mask(X86_FEATURE_CMT)        |
-                                            cpufeat_mask(X86_FEATURE_FPU_SEL)    |
-                                            cpufeat_mask(X86_FEATURE_MPX)        |
-                                            cpufeat_mask(X86_FEATURE_CAT)        |
-                                            cpufeat_mask(X86_FEATURE_RDSEED)     |
-                                            cpufeat_mask(X86_FEATURE_ADX)        |
-                                            cpufeat_mask(X86_FEATURE_SMAP)       |
-                                            cpufeat_mask(X86_FEATURE_PCOMMIT)    |
-                                            cpufeat_mask(X86_FEATURE_CLFLUSHOPT) |
-                                            cpufeat_mask(X86_FEATURE_CLWB)       |
-                                            cpufeat_mask(X86_FEATURE_SHA)),
-
-    [cpufeat_word(X86_FEATURE_PREFETCHWT1)] = (cpufeat_mask(X86_FEATURE_PREFETCHWT1)),
-
-    [cpufeat_word(X86_FEATURE_ITSC)] = (cpufeat_mask(X86_FEATURE_ITSC)),
-
-    [cpufeat_word(X86_FEATURE_CLZERO)] = (cpufeat_mask(X86_FEATURE_CLZERO)),
-};
-
 const uint32_t inverted_features[XEN_NR_FEATURESET_ENTRIES] =
 {
     [cpufeat_word(X86_FEATURE_FPU_SEL)] = cpufeat_mask(X86_FEATURE_FPU_SEL),
diff --git a/xen/arch/x86/cpuid/gen-feature-deps.py b/xen/arch/x86/cpuid/gen-feature-deps.py
index f0ecbba..1b61542 100755
--- a/xen/arch/x86/cpuid/gen-feature-deps.py
+++ b/xen/arch/x86/cpuid/gen-feature-deps.py
@@ -42,6 +42,15 @@ with open(path.join(os.environ["XEN_ROOT"],
         # Construct a reverse mapping of value to name
         names[val] = name
 
+# Features shared between 1d and e1d.
+shared_1d = (FPU, VME, DE, PSE, TSC, MSR, PAE, MCE, CX8, APIC,
+             MTRR, PGE, MCA, CMOV, PAT, PSE36, MMX, FXSR)
+
+# All defined features, other than shared ones.
+all_features = []
+
+for f in (x for x in names.keys() if not x in shared_1d):
+    all_features.append(f)
 
 # Dependences specified as a dictionary of tuples: The feature in the key
 # is a direct dependency of each of the features in the tuple.
@@ -95,7 +104,7 @@ for feat in deep_features:
 
     deep_deps[feat] = seen[1:]
 
-def format_featurset(fs):
+def format_featurset(fs, shared = False):
 
     words = {}
     res = "\n"
@@ -112,7 +121,11 @@ def format_featurset(fs):
     for w in sorted(words.keys()):
         wf = sorted(words[w])
 
-        res += "        [cpufeat_word(X86_FEATURE_%s)] = (\n" % (names[wf[0]], )
+        if shared and wf[0] in (SEP, SYSCALL):
+            res += "        [cpufeat_word(X86_FEATURE_%s)] = (SHARED_1d |\n" \
+                   % (names[wf[0]], )
+        else:
+            res += "        [cpufeat_word(X86_FEATURE_%s)] = (\n" % (names[wf[0]], )
 
         res += " |\n".join(
             "            cpufeat_mask(X86_FEATURE_%s)" %
@@ -130,8 +143,12 @@ with open(path.join(os.environ["XEN_ROOT"],
  */
 #include "cpuid-private.h"
 
+const uint32_t known_features[XEN_NR_FEATURESET_ENTRIES] =
+{%s
+};
+
 const struct tagged_featureset deep_deps[] =
-{""" % (sys.argv[0],))
+{""" % (sys.argv[0], format_featurset(all_features, True)))
 
     for d in sorted(deep_deps.keys()):
         f.write("""
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 17/31] xen/x86: Clear dependent features when clearing a cpu cap
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (15 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 16/31] x86: Automatically generate known_features Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2015-12-16 21:24 ` [PATCH RFC 18/31] xen/x86: Improve disabling of features which have dependencies Andrew Cooper
                   ` (13 subsequent siblings)
  30 siblings, 0 replies; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Jan Beulich

When clearing a cpu cap, clear all dependent features.  This avoids having a
featureset with intermediate features disabled, but leaf features enabled.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
---
 xen/arch/x86/cpu/common.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c
index b48ce58..ba42ac0 100644
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -49,8 +49,24 @@ static unsigned int __cpuinitdata cleared_caps[NCAPINTS];
 
 void __init setup_clear_cpu_cap(unsigned int cap)
 {
+	const struct tagged_featureset *dfs;
+	unsigned int i;
+
+	if ( test_bit(cap, cleared_caps) )
+		return;
+
 	__clear_bit(cap, boot_cpu_data.x86_capability);
 	__set_bit(cap, cleared_caps);
+
+	dfs = lookup_deep_deps(cap);
+
+	if ( !dfs )
+		return;
+
+	for ( i = 0; i < ARRAY_SIZE(dfs->fs); ++i ) {
+		cleared_caps[i] |= dfs->fs[i];
+		boot_cpu_data.x86_capability[i] &= ~dfs->fs[i];
+	}
 }
 
 static void default_init(struct cpuinfo_x86 * c)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 18/31] xen/x86: Improve disabling of features which have dependencies
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (16 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 17/31] xen/x86: Clear dependent features when clearing a cpu cap Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2016-01-21 16:48   ` Jan Beulich
  2015-12-16 21:24 ` [PATCH RFC 19/31] tools/libxc: Sanitise guest featuresets Andrew Cooper
                   ` (12 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Jan Beulich

APIC and XSAVE have dependent features, which also need disabling if Xen
chooses to disable a feature.

Use setup_clear_cpu_cap() rather than clear_bit(), as it takes care of
dependent features as well.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
---
 xen/arch/x86/apic.c       |  4 ++--
 xen/arch/x86/cpu/common.c | 12 +++---------
 xen/arch/x86/xstate.c     |  7 ++++++-
 3 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c
index 2c9ae4e..1cfcf87 100644
--- a/xen/arch/x86/apic.c
+++ b/xen/arch/x86/apic.c
@@ -1365,7 +1365,7 @@ void pmu_apic_interrupt(struct cpu_user_regs *regs)
 int __init APIC_init_uniprocessor (void)
 {
     if (enable_local_apic < 0)
-        clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
+        setup_clear_cpu_cap(X86_FEATURE_APIC);
 
     if (!smp_found_config && !cpu_has_apic) {
         skip_ioapic_setup = 1;
@@ -1378,7 +1378,7 @@ int __init APIC_init_uniprocessor (void)
     if (!cpu_has_apic && APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
         printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n",
                boot_cpu_physical_apicid);
-        clear_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
+        setup_clear_cpu_cap(X86_FEATURE_APIC);
         skip_ioapic_setup = 1;
         return -1;
     }
diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c
index ba42ac0..7b89ebd 100644
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -16,9 +16,6 @@
 
 #include "cpu.h"
 
-static bool_t __cpuinitdata use_xsave = 1;
-boolean_param("xsave", use_xsave);
-
 bool_t __devinitdata opt_arat = 1;
 boolean_param("arat", opt_arat);
 
@@ -335,12 +332,6 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
 	if (this_cpu->c_init)
 		this_cpu->c_init(c);
 
-        /* Initialize xsave/xrstor features */
-	if ( !use_xsave )
-		clear_bit(X86_FEATURE_XSAVE, boot_cpu_data.x86_capability);
-
-	if ( cpu_has_xsave )
-		xstate_init(c);
 
 	/*
 	 * The vendor-specific functions might have changed features.  Now
@@ -363,6 +354,9 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
 
 	/* Now the feature flags better reflect actual CPU features! */
 
+	if ( cpu_has_xsave )
+		xstate_init(c);
+
 #ifdef NOISY_CAPS
 	printk(KERN_DEBUG "CPU: After all inits, caps:");
 	for (i = 0; i < NCAPINTS; i++)
diff --git a/xen/arch/x86/xstate.c b/xen/arch/x86/xstate.c
index c6238d9..55d1360 100644
--- a/xen/arch/x86/xstate.c
+++ b/xen/arch/x86/xstate.c
@@ -278,11 +278,16 @@ unsigned int xstate_ctxt_size(u64 xcr0)
 /* Collect the information of processor's extended state */
 void xstate_init(struct cpuinfo_x86 *c)
 {
+    static bool_t __initdata use_xsave = 1;
+
     bool_t bsp = c == &boot_cpu_data;
     u32 eax, ebx, ecx, edx;
     u64 feature_mask;
 
-    if ( boot_cpu_data.cpuid_level < XSTATE_CPUID )
+    boolean_param("xsave", use_xsave);
+
+    if ( (bsp && !use_xsave) ||
+         boot_cpu_data.cpuid_level < XSTATE_CPUID )
     {
         BUG_ON(!bsp);
         setup_clear_cpu_cap(X86_FEATURE_XSAVE);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 19/31] tools/libxc: Sanitise guest featuresets
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (17 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 18/31] xen/x86: Improve disabling of features which have dependencies Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2016-01-05 16:05   ` Ian Campbell
  2015-12-16 21:24 ` [PATCH RFC 20/31] x86: Improvements to in-hypervisor cpuid sanity checks Andrew Cooper
                   ` (11 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Ian Jackson, Ian Campbell, Wei Liu

When generating a VM featureset, clearing individual features is problematic
if a feature has dependent features.

Instead of disabling individual features, collect all disabling together in
sanitise_featureset(), and perform deep dependency removal on the result, to
remove all impacted features.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Ian Campbell <Ian.Campbell@citrix.com>
CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
CC: Wei Liu <wei.liu2@citrix.com>
---
 tools/libxc/xc_cpuid_x86.c | 144 +++++++++++++++++++++------------------------
 1 file changed, 67 insertions(+), 77 deletions(-)

diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
index 3f39306..6c8995f 100644
--- a/tools/libxc/xc_cpuid_x86.c
+++ b/tools/libxc/xc_cpuid_x86.c
@@ -21,14 +21,15 @@
 
 #include <stdlib.h>
 #include <stdbool.h>
+#include <limits.h>
 #include "xc_private.h"
-#include <xen/arch-x86/featureset.h>
+#include "cpuid-private.h"
 #include <xen/hvm/params.h>
 #include <xen/sysctl.h>
 
 #define bitmaskof(idx)      (1u << ((idx) & 31))
-#define clear_bit(idx, dst) ((dst) &= ~bitmaskof(idx))
-#define set_bit(idx, dst)   ((dst) |=  bitmaskof(idx))
+#define clear_feature(idx, dst) ((dst) &= ~bitmaskof(idx))
+#define set_feature(idx, dst)   ((dst) |=  bitmaskof(idx))
 
 #define DEF_MAX_BASE 0x0000000du
 #define DEF_MAX_INTELEXT  0x80000008u
@@ -212,20 +213,6 @@ static void amd_xc_cpuid_policy(xc_interface *xch,
             regs[0] = DEF_MAX_AMDEXT;
         break;
 
-    case 0x80000001:
-        if ( !info->pae )
-            clear_bit(X86_FEATURE_PAE, regs[3]);
-
-        if ( !info->nestedhvm )
-            clear_bit(X86_FEATURE_SVM, regs[2]);
-
-        if ( info->xfeature_mask == 0 )
-        {
-            clear_bit(X86_FEATURE_FMA4, regs[2]);
-            clear_bit(X86_FEATURE_LWP, regs[2]);
-        }
-        break;
-
     case 0x80000008:
         /*
          * ECX[15:12] is ApicIdCoreSize: ECX[7:0] is NumberOfCores (minus one).
@@ -272,11 +259,6 @@ static void intel_xc_cpuid_policy(xc_interface *xch,
 {
     switch ( input[0] )
     {
-    case 0x00000001:
-        if ( !info->nestedhvm )
-            clear_bit(X86_FEATURE_VMXE, regs[2]);
-        break;
-
     case 0x00000004:
         /*
          * EAX[31:26] is Maximum Cores Per Package (minus one).
@@ -375,20 +357,6 @@ static void xc_cpuid_hvm_policy(xc_interface *xch,
 
         regs[2] = info->featureset[XEN_FEATURESET_1c];
         regs[3] = info->featureset[XEN_FEATURESET_1d];
-
-        if ( info->xfeature_mask == 0 )
-        {
-            clear_bit(X86_FEATURE_AVX, regs[2]);
-            clear_bit(X86_FEATURE_F16C, regs[2]);
-            clear_bit(X86_FEATURE_FMA, regs[2]);
-            clear_bit(X86_FEATURE_XSAVE, regs[2]);
-        }
-
-        if ( !info->pae )
-        {
-            clear_bit(X86_FEATURE_PAE, regs[3]);
-            clear_bit(X86_FEATURE_PSE36, regs[3]);
-        }
         break;
 
     case 0x00000007: /* Intel-defined CPU features */
@@ -416,15 +384,6 @@ static void xc_cpuid_hvm_policy(xc_interface *xch,
     case 0x80000001:
         regs[2] = info->featureset[XEN_FEATURESET_e1c];
         regs[3] = info->featureset[XEN_FEATURESET_e1d];
-
-        if ( !info->pae )
-        {
-            clear_bit(X86_FEATURE_LAHF_LM, regs[2]);
-            clear_bit(X86_FEATURE_LM, regs[3]);
-            clear_bit(X86_FEATURE_NX, regs[3]);
-            clear_bit(X86_FEATURE_PSE36, regs[3]);
-            clear_bit(X86_FEATURE_PAGE1GB, regs[3]);
-        }
         break;
 
     case 0x80000007:
@@ -473,23 +432,6 @@ static void xc_cpuid_pv_policy(xc_interface *xch,
     case 0x00000001:
         regs[2] = info->featureset[XEN_FEATURESET_1c];
         regs[3] = info->featureset[XEN_FEATURESET_1d];
-
-        if ( !info->pv64 )
-            clear_bit(X86_FEATURE_CX16, regs[2]);
-
-        if ( info->xfeature_mask == 0 )
-        {
-            clear_bit(X86_FEATURE_XSAVE, regs[2]);
-            clear_bit(X86_FEATURE_AVX, regs[2]);
-            clear_bit(X86_FEATURE_F16C, regs[2]);
-            clear_bit(X86_FEATURE_FMA, regs[2]);
-        }
-
-        if ( !info->pvh )
-        {
-            clear_bit(X86_FEATURE_PSE, regs[3]);
-            clear_bit(X86_FEATURE_PGE, regs[3]);
-        }
         break;
 
     case 0x00000007:
@@ -513,19 +455,6 @@ static void xc_cpuid_pv_policy(xc_interface *xch,
     case 0x80000001:
         regs[2] = info->featureset[XEN_FEATURESET_e1c];
         regs[3] = info->featureset[XEN_FEATURESET_e1d];
-
-        if ( !info->pv64 )
-        {
-            clear_bit(X86_FEATURE_LM, regs[3]);
-            clear_bit(X86_FEATURE_LAHF_LM, regs[2]);
-        }
-
-        if ( !info->pvh )
-        {
-            clear_bit(X86_FEATURE_PSE, regs[3]);
-            clear_bit(X86_FEATURE_PGE, regs[3]);
-            clear_bit(X86_FEATURE_PAGE1GB, regs[3]);
-        }
         break;
 
     case 0x00000005: /* MONITOR/MWAIT */
@@ -605,6 +534,65 @@ void xc_cpuid_to_str(const unsigned int *regs, char **strs)
     }
 }
 
+static void sanitise_featureset(struct cpuid_domain_info *info)
+{
+    uint32_t disabled_features[XEN_NR_FEATURESET_ENTRIES];
+    unsigned int i, b;
+
+    if ( info->hvm )
+    {
+        /* HVM Guest */
+
+        if ( !info->pae )
+            clear_bit(X86_FEATURE_PAE, info->featureset);
+
+        if ( !info->nestedhvm )
+        {
+            clear_bit(X86_FEATURE_SVM, info->featureset);
+            clear_bit(X86_FEATURE_VMXE, info->featureset);
+        }
+
+    }
+    else
+    {
+        /* PV or PVH Guest */
+
+        if ( !info->pv64 )
+            clear_bit(X86_FEATURE_LM, info->featureset);
+
+        if ( !info->pvh )
+        {
+            clear_bit(X86_FEATURE_PSE, info->featureset);
+            clear_bit(X86_FEATURE_PSE36, info->featureset);
+            clear_bit(X86_FEATURE_PGE, info->featureset);
+            clear_bit(X86_FEATURE_PAGE1GB, info->featureset);
+        }
+    }
+
+    if ( info->xfeature_mask == 0 )
+        clear_bit(X86_FEATURE_XSAVE, info->featureset);
+
+    /* Disable deep dependencies of disabled features. */
+
+    for ( i = 0; i < ARRAY_SIZE(disabled_features); ++i )
+        disabled_features[i] = ~info->featureset[i] & deep_dep_features[i];
+
+    for ( b = 0; b < sizeof(disabled_features) * CHAR_BIT; ++b )
+    {
+        const struct tagged_featureset *dfs;
+
+        if ( !test_bit(b, disabled_features) ||
+             !(dfs = lookup_deep_deps(b)) )
+             continue;
+
+        for ( i = 0; i < ARRAY_SIZE(disabled_features); ++i )
+        {
+            info->featureset[i] &= ~dfs->fs[i];
+            disabled_features[i] &= ~dfs->fs[i];
+        }
+    }
+}
+
 static int __xc_cpuid_apply_policy(xc_interface *xch, domid_t domid,
                                    uint32_t *featureset,
                                    unsigned int nr_features)
@@ -628,6 +616,8 @@ static int __xc_cpuid_apply_policy(xc_interface *xch, domid_t domid,
     else
         ext_max = (regs[0] <= DEF_MAX_INTELEXT) ? regs[0] : DEF_MAX_INTELEXT;
 
+    sanitise_featureset(&info);
+
     input[0] = 0;
     input[1] = XEN_CPUID_INPUT_UNUSED;
     for ( ; ; )
@@ -811,9 +801,9 @@ int xc_cpuid_set(
                 val = polval;
 
             if ( val )
-                set_bit(31 - j, regs[i]);
+                set_feature(31 - j, regs[i]);
             else
-                clear_bit(31 - j, regs[i]);
+                clear_feature(31 - j, regs[i]);
 
             config_transformed[i][j] = config[i][j];
             if ( config[i][j] == 's' )
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 20/31] x86: Improvements to in-hypervisor cpuid sanity checks
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (18 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 19/31] tools/libxc: Sanitise guest featuresets Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2016-01-21 17:02   ` Jan Beulich
  2015-12-16 21:24 ` [PATCH RFC 21/31] x86/domctl: Break out logic to update domain state from cpuid information Andrew Cooper
                   ` (10 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Jan Beulich

* Use the boot-generated pv and hvm featureset to clamp the visible features,
  rather than picking and choosing at individual features.  This subsumes most
  of the feature availability checks.
* More use of compiler-visible &'s and |'s, rather than clear,set bit.
* Remove logic which hides PSE36 out of PAE mode.  This is not how real
  hardware behaves.
* Improve logic to set OSXSAVE.  The bit is cleared by virtue of not being
  valid in a featureset, and is a strict fast-forward from %cr4.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
---
 xen/arch/x86/hvm/hvm.c |  62 ++++++++++++++++-------------
 xen/arch/x86/traps.c   | 106 ++++++++++++-------------------------------------
 2 files changed, 60 insertions(+), 108 deletions(-)

diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index ea80b1e..240e052 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -69,6 +69,7 @@
 #include <public/memory.h>
 #include <public/vm_event.h>
 #include <public/arch-x86/cpuid.h>
+#include <asm/cpuid.h>
 
 bool_t __read_mostly hvm_enabled;
 
@@ -4486,43 +4487,39 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
         /* Fix up VLAPIC details. */
         *ebx &= 0x00FFFFFFu;
         *ebx |= (v->vcpu_id * 2) << 24;
+
+        *ecx &= hvm_featureset[XEN_FEATURESET_1c];
+        *edx &= hvm_featureset[XEN_FEATURESET_1d];
+
         if ( vlapic_hw_disabled(vcpu_vlapic(v)) )
-            __clear_bit(X86_FEATURE_APIC & 31, edx);
+            *edx &= ~cpufeat_bit(X86_FEATURE_APIC);
 
         /* Fix up OSXSAVE. */
-        if ( cpu_has_xsave )
-            *ecx |= (v->arch.hvm_vcpu.guest_cr[4] & X86_CR4_OSXSAVE) ?
-                     cpufeat_mask(X86_FEATURE_OSXSAVE) : 0;
+        if ( v->arch.hvm_vcpu.guest_cr[4] & X86_CR4_OSXSAVE )
+            *ecx |= cpufeat_mask(X86_FEATURE_OSXSAVE);
 
         /* Don't expose PCID to non-hap hvm. */
         if ( !hap_enabled(d) )
             *ecx &= ~cpufeat_mask(X86_FEATURE_PCID);
-
-        /* Only provide PSE36 when guest runs in 32bit PAE or in long mode */
-        if ( !(hvm_pae_enabled(v) || hvm_long_mode_enabled(v)) )
-            *edx &= ~cpufeat_mask(X86_FEATURE_PSE36);
         break;
-    case 0x7:
-        if ( (count == 0) && !cpu_has_smep )
-            *ebx &= ~cpufeat_mask(X86_FEATURE_SMEP);
 
-        if ( (count == 0) && !cpu_has_smap )
-            *ebx &= ~cpufeat_mask(X86_FEATURE_SMAP);
-
-        /* Don't expose MPX to hvm when VMX support is not available */
-        if ( (count == 0) &&
-             (!(vmx_vmexit_control & VM_EXIT_CLEAR_BNDCFGS) ||
-              !(vmx_vmentry_control & VM_ENTRY_LOAD_BNDCFGS)) )
-            *ebx &= ~cpufeat_mask(X86_FEATURE_MPX);
+    case 0x7:
+        if ( count == 0 )
+        {
+            *ebx &= hvm_featureset[XEN_FEATURESET_7b0];
+            *ecx &= hvm_featureset[XEN_FEATURESET_7c0];
 
-        /* Don't expose INVPCID to non-hap hvm. */
-        if ( (count == 0) && !hap_enabled(d) )
-            *ebx &= ~cpufeat_mask(X86_FEATURE_INVPCID);
+            /* Don't expose INVPCID to non-hap hvm. */
+            if ( !hap_enabled(d) )
+                *ebx &= ~cpufeat_mask(X86_FEATURE_INVPCID);
+        }
         break;
+
     case 0xb:
         /* Fix the x2APIC identifier. */
         *edx = v->vcpu_id * 2;
         break;
+
     case 0xd:
         /* EBX value of main leaf 0 depends on enabled xsave features */
         if ( count == 0 && v->arch.xcr0 ) 
@@ -4539,9 +4536,18 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
                     *ebx = _eax + _ebx;
             }
         }
+        else if ( count == 1 )
+        {
+            *eax &= hvm_featureset[XEN_FEATURESET_Da1];
+            if ( !(*eax & cpufeat_mask(X86_FEATURE_XSAVES)) )
+                 *ebx = *ecx = *edx = 0;
+        }
         break;
 
     case 0x80000001:
+        *ecx &= hvm_featureset[XEN_FEATURESET_e1c];
+        *edx &= hvm_featureset[XEN_FEATURESET_e1d];
+
         /* We expose RDTSCP feature to guest only when
            tsc_mode == TSC_MODE_DEFAULT and host_tsc_is_safe() returns 1 */
         if ( d->arch.tsc_mode != TSC_MODE_DEFAULT ||
@@ -4550,12 +4556,10 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
         /* Hide 1GB-superpage feature if we can't emulate it. */
         if (!hvm_pse1gb_supported(d))
             *edx &= ~cpufeat_mask(X86_FEATURE_PAGE1GB);
-        /* Only provide PSE36 when guest runs in 32bit PAE or in long mode */
-        if ( !(hvm_pae_enabled(v) || hvm_long_mode_enabled(v)) )
-            *edx &= ~cpufeat_mask(X86_FEATURE_PSE36);
-        /* Hide data breakpoint extensions if the hardware has no support. */
-        if ( !boot_cpu_has(X86_FEATURE_DBEXT) )
-            *ecx &= ~cpufeat_mask(X86_FEATURE_DBEXT);
+        break;
+
+    case 0x80000007:
+        *edx &= hvm_featureset[XEN_FEATURESET_e7d];
         break;
 
     case 0x80000008:
@@ -4573,6 +4577,8 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
         hvm_cpuid(0x80000001, NULL, NULL, NULL, &_edx);
         *eax = (*eax & ~0xffff00) | (_edx & cpufeat_mask(X86_FEATURE_LM)
                                      ? 0x3000 : 0x2000);
+
+        *ebx &= hvm_featureset[XEN_FEATURESET_e8b];
         break;
     }
 }
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 99a0499..76ecd34 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -73,6 +73,7 @@
 #include <asm/hpet.h>
 #include <asm/vpmu.h>
 #include <public/arch-x86/cpuid.h>
+#include <asm/cpuid.h>
 #include <xsm/xsm.h>
 
 /*
@@ -864,69 +865,27 @@ void pv_cpuid(struct cpu_user_regs *regs)
 
     cpuid_count(a, c, &a, &b, &c, &d);
 
-    if ( (regs->eax & 0x7fffffff) == 0x00000001 )
-    {
-        /* Modify Feature Information. */
-        if ( !cpu_has_apic )
-            __clear_bit(X86_FEATURE_APIC, &d);
-
-        if ( !is_pvh_domain(currd) )
-        {
-            __clear_bit(X86_FEATURE_PSE, &d);
-            __clear_bit(X86_FEATURE_PGE, &d);
-            __clear_bit(X86_FEATURE_PSE36, &d);
-            __clear_bit(X86_FEATURE_VME, &d);
-        }
-    }
-
     switch ( regs->_eax )
     {
     case 0x00000001:
-        /* Modify Feature Information. */
-        if ( !cpu_has_sep )
-            __clear_bit(X86_FEATURE_SEP, &d);
-        __clear_bit(X86_FEATURE_DS, &d);
-        __clear_bit(X86_FEATURE_ACC, &d);
-        __clear_bit(X86_FEATURE_PBE, &d);
-        if ( is_pvh_domain(currd) )
-            __clear_bit(X86_FEATURE_MTRR, &d);
-
-        __clear_bit(X86_FEATURE_DTES64 % 32, &c);
-        __clear_bit(X86_FEATURE_MWAIT % 32, &c);
-        __clear_bit(X86_FEATURE_DSCPL % 32, &c);
-        __clear_bit(X86_FEATURE_VMXE % 32, &c);
-        __clear_bit(X86_FEATURE_SMXE % 32, &c);
-        __clear_bit(X86_FEATURE_TM2 % 32, &c);
-        if ( is_pv_32bit_domain(currd) )
-            __clear_bit(X86_FEATURE_CX16 % 32, &c);
-        __clear_bit(X86_FEATURE_XTPR % 32, &c);
-        __clear_bit(X86_FEATURE_PDCM % 32, &c);
-        __clear_bit(X86_FEATURE_PCID % 32, &c);
-        __clear_bit(X86_FEATURE_DCA % 32, &c);
-        if ( !cpu_has_xsave )
-        {
-            __clear_bit(X86_FEATURE_XSAVE % 32, &c);
-            __clear_bit(X86_FEATURE_AVX % 32, &c);
-        }
-        if ( !cpu_has_apic )
-           __clear_bit(X86_FEATURE_X2APIC % 32, &c);
-        __set_bit(X86_FEATURE_HYPERVISOR % 32, &c);
+        c &= pv_featureset[XEN_FEATURESET_1c];
+        d &= pv_featureset[XEN_FEATURESET_1d];
+
+        if ( curr->arch.pv_vcpu.ctrlreg[4] & X86_CR4_OSXSAVE )
+            c |= cpufeat_mask(X86_FEATURE_OSXSAVE);
+
+        c |= cpufeat_mask(X86_FEATURE_HYPERVISOR);
         break;
 
     case 0x00000007:
         if ( regs->_ecx == 0 )
-            b &= (cpufeat_mask(X86_FEATURE_BMI1) |
-                  cpufeat_mask(X86_FEATURE_HLE)  |
-                  cpufeat_mask(X86_FEATURE_AVX2) |
-                  cpufeat_mask(X86_FEATURE_BMI2) |
-                  cpufeat_mask(X86_FEATURE_ERMS) |
-                  cpufeat_mask(X86_FEATURE_RTM)  |
-                  cpufeat_mask(X86_FEATURE_RDSEED)  |
-                  cpufeat_mask(X86_FEATURE_ADX)  |
-                  cpufeat_mask(X86_FEATURE_FSGSBASE));
+        {
+            b &= pv_featureset[XEN_FEATURESET_7b0];
+            c &= pv_featureset[XEN_FEATURESET_7c0];
+        }
         else
-            b = 0;
-        a = c = d = 0;
+            b = c = 0;
+        a = d = 0;
         break;
 
     case XSTATE_CPUID:
@@ -935,36 +894,23 @@ void pv_cpuid(struct cpu_user_regs *regs)
             goto unsupported;
         if ( regs->_ecx == 1 )
         {
-            a &= boot_cpu_data.x86_capability[cpufeat_word(X86_FEATURE_XSAVEOPT)];
-            if ( !cpu_has_xsaves )
+            a &= pv_featureset[XEN_FEATURESET_Da1];
+            if ( !(a & cpufeat_mask(X86_FEATURE_XSAVES)) )
                 b = c = d = 0;
         }
         break;
 
     case 0x80000001:
-        /* Modify Feature Information. */
-        if ( is_pv_32bit_domain(currd) )
-        {
-            __clear_bit(X86_FEATURE_LM % 32, &d);
-            __clear_bit(X86_FEATURE_LAHF_LM % 32, &c);
-        }
-        if ( is_pv_32bit_domain(currd) &&
-             boot_cpu_data.x86_vendor != X86_VENDOR_AMD )
-            __clear_bit(X86_FEATURE_SYSCALL % 32, &d);
-        __clear_bit(X86_FEATURE_PAGE1GB % 32, &d);
-        __clear_bit(X86_FEATURE_RDTSCP % 32, &d);
-
-        __clear_bit(X86_FEATURE_SVM % 32, &c);
-        if ( !cpu_has_apic )
-           __clear_bit(X86_FEATURE_EXTAPIC % 32, &c);
-        __clear_bit(X86_FEATURE_OSVW % 32, &c);
-        __clear_bit(X86_FEATURE_IBS % 32, &c);
-        __clear_bit(X86_FEATURE_SKINIT % 32, &c);
-        __clear_bit(X86_FEATURE_WDT % 32, &c);
-        __clear_bit(X86_FEATURE_LWP % 32, &c);
-        __clear_bit(X86_FEATURE_NODEID_MSR % 32, &c);
-        __clear_bit(X86_FEATURE_TOPOEXT % 32, &c);
-        __clear_bit(X86_FEATURE_MWAITX % 32, &c);
+        c &= pv_featureset[XEN_FEATURESET_e1c];
+        d &= pv_featureset[XEN_FEATURESET_e1d];
+        break;
+
+    case 0x80000007:
+        d &= pv_featureset[XEN_FEATURESET_e7d];
+        break;
+
+    case 0x80000008:
+        b &= pv_featureset[XEN_FEATURESET_e8b];
         break;
 
     case 0x0000000a: /* Architectural Performance Monitor Features (Intel) */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 21/31] x86/domctl: Break out logic to update domain state from cpuid information
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (19 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 20/31] x86: Improvements to in-hypervisor cpuid sanity checks Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2016-01-21 17:05   ` Jan Beulich
  2015-12-16 21:24 ` [PATCH RFC 22/31] x86/cpu: Move set_cpumask() calls into c_early_init() Andrew Cooper
                   ` (9 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Jan Beulich

Later changes will add to this logic.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
---
 xen/arch/x86/domctl.c | 64 ++++++++++++++++++++++++++++-----------------------
 1 file changed, 35 insertions(+), 29 deletions(-)

diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index bf62a88..5eb8f00 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -47,6 +47,40 @@ static int gdbsx_guest_mem_io(domid_t domid, struct xen_domctl_gdbsx_memio *iop)
     return iop->remain ? -EFAULT : 0;
 }
 
+static void update_domain_cpuid_info(struct domain *d,
+                                     const xen_domctl_cpuid_t *ctl)
+{
+    switch ( ctl->input[0] )
+    {
+    case 0: {
+        union {
+            typeof(boot_cpu_data.x86_vendor_id) str;
+            struct {
+                uint32_t ebx, edx, ecx;
+            } reg;
+        } vendor_id = {
+            .reg = {
+                .ebx = ctl->ebx,
+                .edx = ctl->edx,
+                .ecx = ctl->ecx
+            }
+        };
+
+        d->arch.x86_vendor = get_cpu_vendor(vendor_id.str, gcv_guest);
+        break;
+    }
+
+    case 1:
+        d->arch.x86 = (ctl->eax >> 8) & 0xf;
+        if ( d->arch.x86 == 0xf )
+            d->arch.x86 += (ctl->eax >> 20) & 0xff;
+        d->arch.x86_model = (ctl->eax >> 4) & 0xf;
+        if ( d->arch.x86 >= 0x6 )
+            d->arch.x86_model |= (ctl->eax >> 12) & 0xf0;
+        break;
+    }
+}
+
 #define MAX_IOPORTS 0x10000
 
 long arch_do_domctl(
@@ -697,36 +731,8 @@ long arch_do_domctl(
             ret = -ENOENT;
 
         if ( !ret )
-        {
-            switch ( ctl->input[0] )
-            {
-            case 0: {
-                union {
-                    typeof(boot_cpu_data.x86_vendor_id) str;
-                    struct {
-                        uint32_t ebx, edx, ecx;
-                    } reg;
-                } vendor_id = {
-                    .reg = {
-                        .ebx = ctl->ebx,
-                        .edx = ctl->edx,
-                        .ecx = ctl->ecx
-                    }
-                };
+            update_domain_cpuid_info(d, ctl);
 
-                d->arch.x86_vendor = get_cpu_vendor(vendor_id.str, gcv_guest);
-                break;
-            }
-            case 1:
-                d->arch.x86 = (ctl->eax >> 8) & 0xf;
-                if ( d->arch.x86 == 0xf )
-                    d->arch.x86 += (ctl->eax >> 20) & 0xff;
-                d->arch.x86_model = (ctl->eax >> 4) & 0xf;
-                if ( d->arch.x86 >= 0x6 )
-                    d->arch.x86_model |= (ctl->eax >> 12) & 0xf0;
-                break;
-            }
-        }
         break;
     }
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 22/31] x86/cpu: Move set_cpumask() calls into c_early_init()
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (20 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 21/31] x86/domctl: Break out logic to update domain state from cpuid information Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2016-01-21 17:08   ` Jan Beulich
  2015-12-16 21:24 ` [PATCH RFC 23/31] xen/x86: Export cpuid levelling capabilities via SYSCTL Andrew Cooper
                   ` (8 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Jan Beulich

Before c/s 44e24f8567 "x86: don't call generic_identify() redundantly", the
commandline-provided masks would take effect in Xen's view of the features.

As the masks got applied after the query for features, the redundant call to
generic_identify() would clobber the wrong feature information with the new,
correct information.

Move the set_cpumask() calls into c_early_init() so their effects take place
before the main query for features in generic_identify().

The cpuid_mask_* command line parameters now correctly limit the entire
system, although the subsequent changes will replace the need to use these
parameters for heterogeneous levelling purposes.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
---
 xen/arch/x86/cpu/amd.c   |  8 ++++++--
 xen/arch/x86/cpu/intel.c | 33 +++++++++++++++++----------------
 2 files changed, 23 insertions(+), 18 deletions(-)

diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c
index 5d22863..265fbc0 100644
--- a/xen/arch/x86/cpu/amd.c
+++ b/xen/arch/x86/cpu/amd.c
@@ -424,6 +424,11 @@ static void __devinit amd_get_topology(struct cpuinfo_x86 *c)
                                                          c->cpu_core_id);
 }
 
+static void __devinit early_init_amd(struct cpuinfo_x86 *c)
+{
+	set_cpuidmask(c);
+}
+
 static void __devinit init_amd(struct cpuinfo_x86 *c)
 {
 	u32 l, h;
@@ -615,14 +620,13 @@ static void __devinit init_amd(struct cpuinfo_x86 *c)
 	if ((smp_processor_id() == 1) && c1_ramping_may_cause_clock_drift(c))
 		disable_c1_ramping();
 
-	set_cpuidmask(c);
-
 	check_syscfg_dram_mod_en();
 }
 
 static const struct cpu_dev amd_cpu_dev = {
 	.c_vendor	= "AMD",
 	.c_ident 	= { "AuthenticAMD" },
+	.c_early_init	= early_init_amd,
 	.c_init		= init_amd,
 };
 
diff --git a/xen/arch/x86/cpu/intel.c b/xen/arch/x86/cpu/intel.c
index bd595a5..d251b53 100644
--- a/xen/arch/x86/cpu/intel.c
+++ b/xen/arch/x86/cpu/intel.c
@@ -182,6 +182,23 @@ static void early_init_intel(struct cpuinfo_x86 *c)
 	if (boot_cpu_data.x86 == 0xF && boot_cpu_data.x86_model == 3 &&
 	    (boot_cpu_data.x86_mask == 3 || boot_cpu_data.x86_mask == 4))
 		paddr_bits = 36;
+
+	if (c == &boot_cpu_data && c->x86 == 6) {
+		if (probe_intel_cpuid_faulting())
+			__set_bit(X86_FEATURE_CPUID_FAULTING,
+				  c->x86_capability);
+	} else if (boot_cpu_has(X86_FEATURE_CPUID_FAULTING)) {
+		BUG_ON(!probe_intel_cpuid_faulting());
+		__set_bit(X86_FEATURE_CPUID_FAULTING, c->x86_capability);
+	}
+
+	if (!cpu_has_cpuid_faulting)
+		set_cpuidmask(c);
+	else if ((c == &boot_cpu_data) &&
+		 (~(opt_cpuid_mask_ecx & opt_cpuid_mask_edx &
+		    opt_cpuid_mask_ext_ecx & opt_cpuid_mask_ext_edx &
+		    opt_cpuid_mask_xsave_eax)))
+		printk("No CPUID feature masking support available\n");
 }
 
 /*
@@ -251,22 +268,6 @@ static void __devinit init_intel(struct cpuinfo_x86 *c)
 		detect_ht(c);
 	}
 
-	if (c == &boot_cpu_data && c->x86 == 6) {
-		if (probe_intel_cpuid_faulting())
-			set_bit(X86_FEATURE_CPUID_FAULTING, c->x86_capability);
-	} else if (boot_cpu_has(X86_FEATURE_CPUID_FAULTING)) {
-		BUG_ON(!probe_intel_cpuid_faulting());
-		set_bit(X86_FEATURE_CPUID_FAULTING, c->x86_capability);
-	}
-
-	if (!cpu_has_cpuid_faulting)
-		set_cpuidmask(c);
-	else if ((c == &boot_cpu_data) &&
-		 (~(opt_cpuid_mask_ecx & opt_cpuid_mask_edx &
-		    opt_cpuid_mask_ext_ecx & opt_cpuid_mask_ext_edx &
-		    opt_cpuid_mask_xsave_eax)))
-		printk("No CPUID feature masking support available\n");
-
 	/* Work around errata */
 	Intel_errata_workarounds(c);
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 23/31] xen/x86: Export cpuid levelling capabilities via SYSCTL
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (21 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 22/31] x86/cpu: Move set_cpumask() calls into c_early_init() Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2016-01-21 17:23   ` Jan Beulich
  2015-12-16 21:24 ` [PATCH RFC 24/31] tools/stubs: Expose host levelling capabilities to userspace Andrew Cooper
                   ` (7 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Tim Deegan, Ian Campbell, Jan Beulich

This allows the toolstack to query what exactly Xen can control in a PV guest
issuing a native `cpuid` instruction.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Tim Deegan <tim@xen.org>
CC: Ian Campbell <Ian.Campbell@citrix.com>
---
 xen/arch/x86/cpu/common.c       |  3 +++
 xen/arch/x86/sysctl.c           |  6 ++++++
 xen/include/asm-x86/processor.h | 13 +++++++++++++
 xen/include/public/sysctl.h     | 30 ++++++++++++++++++++++++++++++
 4 files changed, 52 insertions(+)

diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c
index 7b89ebd..2ad85e0 100644
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -32,6 +32,9 @@ integer_param("cpuid_mask_ext_ecx", opt_cpuid_mask_ext_ecx);
 unsigned int __devinitdata opt_cpuid_mask_ext_edx = ~0u;
 integer_param("cpuid_mask_ext_edx", opt_cpuid_mask_ext_edx);
 
+unsigned int __initdata expected_levelling_cap;
+unsigned int __read_mostly levelling_caps;
+
 const struct cpu_dev *__read_mostly cpu_devs[X86_VENDOR_NUM] = {};
 
 unsigned int paddr_bits __read_mostly = 36;
diff --git a/xen/arch/x86/sysctl.c b/xen/arch/x86/sysctl.c
index 50b2fd4..b01c968 100644
--- a/xen/arch/x86/sysctl.c
+++ b/xen/arch/x86/sysctl.c
@@ -253,6 +253,12 @@ long arch_do_sysctl(
         break;
     }
 
+    case XEN_SYSCTL_get_levelling_caps:
+        sysctl->u.levelling.caps = levelling_caps;
+        if ( __copy_to_guest(u_sysctl, sysctl, 1) )
+            ret = -EFAULT;
+        break;
+
     default:
         ret = -ENOSYS;
         break;
diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h
index f507f5e..b2c3653 100644
--- a/xen/include/asm-x86/processor.h
+++ b/xen/include/asm-x86/processor.h
@@ -572,6 +572,19 @@ void microcode_set_module(unsigned int);
 int microcode_update(XEN_GUEST_HANDLE_PARAM(const_void), unsigned long len);
 int microcode_resume_cpu(unsigned int cpu);
 
+#define LCAP_faulting XEN_SYSCTL_LEVELCAP_faulting
+#define LCAP_1cd      (XEN_SYSCTL_LEVELCAP_1c  | XEN_SYSCTL_LEVELCAP_1d)
+#define LCAP_e1cd     (XEN_SYSCTL_LEVELCAP_e1c | XEN_SYSCTL_LEVELCAP_e1d)
+#define LCAP_Da1      XEN_SYSCTL_LEVELCAP_Da1
+#define LCAP_6c       XEN_SYSCTL_LEVELCAP_6c
+#define LCAP_7ab0     (XEN_SYSCTL_LEVELCAP_7a0 | XEN_SYSCTL_LEVELCAP_7b0)
+
+/*
+ * Expected levelling capabilities (given cpuid vendor/family information),
+ * and levelling capabilities actually available (given MSR probing).
+ */
+extern unsigned int expected_levelling_cap, levelling_caps;
+
 enum get_cpu_vendor {
    gcv_host_early,
    gcv_host_late,
diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
index 3119b7b..7b134c6 100644
--- a/xen/include/public/sysctl.h
+++ b/xen/include/public/sysctl.h
@@ -785,6 +785,34 @@ struct xen_sysctl_featureset {
 typedef struct xen_sysctl_featureset xen_sysctl_featureset_t;
 DEFINE_XEN_GUEST_HANDLE(xen_sysctl_featureset_t);
 
+/*
+ * XEN_SYSCTL_get_levelling_caps (x86 specific)
+ *
+ * Return hardware capabilities concerning masking or faulting of the cpuid
+ * instruction for PV guests.
+ */
+struct xen_sysctl_levelling_caps {
+/*
+ * Featureset array index encoding:
+ * - (possibly) 'e' Extended
+ * - leaf, uppercase hex
+ * - register, lowercase
+ * - (possibly) subleaf
+ */
+#define XEN_SYSCTL_LEVELCAP_faulting (1ul <<  0) /* CPUID faulting    */
+#define XEN_SYSCTL_LEVELCAP_1c       (1ul <<  1) /* 0x00000001.ecx    */
+#define XEN_SYSCTL_LEVELCAP_1d       (1ul <<  2) /* 0x00000001.edx    */
+#define XEN_SYSCTL_LEVELCAP_e1c      (1ul <<  3) /* 0x80000001.ecx    */
+#define XEN_SYSCTL_LEVELCAP_e1d      (1ul <<  4) /* 0x80000001.edx    */
+#define XEN_SYSCTL_LEVELCAP_Da1      (1ul <<  5) /* 0x0000000D:1.eax  */
+#define XEN_SYSCTL_LEVELCAP_6c       (1ul <<  6) /* 0x00000006.ecx    */
+#define XEN_SYSCTL_LEVELCAP_7a0      (1ul <<  7) /* 0x00000007:0.eax  */
+#define XEN_SYSCTL_LEVELCAP_7b0      (1ul <<  8) /* 0x00000007:0.ebx  */
+    uint64_t caps;
+};
+typedef struct xen_sysctl_levelling_caps xen_sysctl_levelling_caps_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_levelling_caps_t);
+
 struct xen_sysctl {
     uint32_t cmd;
 #define XEN_SYSCTL_readconsole                    1
@@ -811,6 +839,7 @@ struct xen_sysctl {
 #define XEN_SYSCTL_psr_cat_op                    23
 #define XEN_SYSCTL_tmem_op                       24
 #define XEN_SYSCTL_get_featureset                25
+#define XEN_SYSCTL_get_levelling_caps            26
     uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */
     union {
         struct xen_sysctl_readconsole       readconsole;
@@ -837,6 +866,7 @@ struct xen_sysctl {
         struct xen_sysctl_psr_cat_op        psr_cat_op;
         struct xen_sysctl_tmem_op           tmem_op;
         struct xen_sysctl_featureset        featureset;
+        struct xen_sysctl_levelling_caps    levelling;
         uint8_t                             pad[128];
     } u;
 };
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 24/31] tools/stubs: Expose host levelling capabilities to userspace
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (22 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 23/31] xen/x86: Export cpuid levelling capabilities via SYSCTL Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2015-12-16 21:24 ` [PATCH RFC 25/31] xen/x86: Common infrastructure for levelling context switching Andrew Cooper
                   ` (6 subsequent siblings)
  30 siblings, 0 replies; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel
  Cc: Wei Liu, Ian Campbell, Andrew Cooper, Ian Jackson, Rob Hoes, David Scott

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Ian Campbell <Ian.Campbell@citrix.com>
CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
CC: Wei Liu <wei.liu2@citrix.com>
CC: David Scott <dave@recoil.org>
CC: Rob Hoes <Rob.Hoes@citrix.com>
---
 tools/libxc/include/xenctrl.h       |  2 ++
 tools/libxc/xc_misc.c               | 14 ++++++++++++++
 tools/ocaml/libs/xc/xenctrl.ml      |  2 ++
 tools/ocaml/libs/xc/xenctrl.mli     |  2 ++
 tools/ocaml/libs/xc/xenctrl_stubs.c | 20 ++++++++++++++++++++
 5 files changed, 40 insertions(+)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index b44aec7..401a6f8 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -2843,6 +2843,8 @@ int xc_psr_cat_get_domain_data(xc_interface *xch, uint32_t domid,
 int xc_psr_cat_get_l3_info(xc_interface *xch, uint32_t socket,
                            uint32_t *cos_max, uint32_t *cbm_len);
 
+int xc_get_levelling_caps(xc_interface *xch, uint64_t *caps);
+
 int xc_get_featureset(xc_interface *xch, uint32_t index,
                       uint32_t *nr_features, uint32_t *featureset);
 #endif
diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c
index 4d7af3d..7707a70 100644
--- a/tools/libxc/xc_misc.c
+++ b/tools/libxc/xc_misc.c
@@ -745,6 +745,20 @@ int xc_get_featureset(xc_interface *xch, uint32_t index,
     return ret;
 }
 
+int xc_get_levelling_caps(xc_interface *xch, uint64_t *caps)
+{
+    DECLARE_SYSCTL;
+    int ret;
+
+    sysctl.cmd = XEN_SYSCTL_get_levelling_caps;
+    ret = do_sysctl(xch, &sysctl);
+
+    if ( !ret )
+        *caps = sysctl.u.levelling.caps;
+
+    return ret;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/tools/ocaml/libs/xc/xenctrl.ml b/tools/ocaml/libs/xc/xenctrl.ml
index 15c7eb0..d651533 100644
--- a/tools/ocaml/libs/xc/xenctrl.ml
+++ b/tools/ocaml/libs/xc/xenctrl.ml
@@ -247,6 +247,8 @@ external version_capabilities: handle -> string =
 type featureset_index = Featureset_host | Featureset_pv | Featureset_hvm
 external get_featureset : handle -> featureset_index -> int64 array = "stub_xc_get_featureset"
 
+external get_levelling_caps : handle -> int64 = "stub_xc_get_levelling_caps"
+
 external watchdog : handle -> int -> int32 -> int
   = "stub_xc_watchdog"
 
diff --git a/tools/ocaml/libs/xc/xenctrl.mli b/tools/ocaml/libs/xc/xenctrl.mli
index 42d6199..1342a5e 100644
--- a/tools/ocaml/libs/xc/xenctrl.mli
+++ b/tools/ocaml/libs/xc/xenctrl.mli
@@ -152,6 +152,8 @@ external version_capabilities : handle -> string
 type featureset_index = Featureset_host | Featureset_pv | Featureset_hvm
 external get_featureset : handle -> featureset_index -> int64 array = "stub_xc_get_featureset"
 
+external get_levelling_caps : handle -> int64 = "stub_xc_get_levelling_caps"
+
 type core_magic = Magic_hvm | Magic_pv
 type core_header = {
   xch_magic : core_magic;
diff --git a/tools/ocaml/libs/xc/xenctrl_stubs.c b/tools/ocaml/libs/xc/xenctrl_stubs.c
index a47473b..3ae2060 100644
--- a/tools/ocaml/libs/xc/xenctrl_stubs.c
+++ b/tools/ocaml/libs/xc/xenctrl_stubs.c
@@ -1255,6 +1255,26 @@ CAMLprim value stub_xc_get_featureset(value xch, value idx)
 	CAMLreturn(bitmap_val);
 }
 
+CAMLprim value stub_xc_get_levelling_caps(value xch)
+{
+	CAMLparam1(xch);
+
+	/* Safe, because of the global ocaml lock. */
+	static uint64_t caps;
+	static bool have_caps;
+
+	if (!have_caps)
+	{
+		int ret = xc_get_levelling_caps(_H(xch), &caps);
+
+		if (ret || (caps > INT64_MAX))
+			failwith_xc(_H(xch));
+		have_caps = true;
+	}
+
+	CAMLreturn(caml_copy_int64(caps));
+}
+
 CAMLprim value stub_xc_watchdog(value xch, value domid, value timeout)
 {
 	CAMLparam3(xch, domid, timeout);
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 25/31] xen/x86: Common infrastructure for levelling context switching
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (23 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 24/31] tools/stubs: Expose host levelling capabilities to userspace Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2016-01-22  8:56   ` Jan Beulich
  2015-12-16 21:24 ` [PATCH RFC 26/31] xen/x86: Rework AMD masking MSR setup Andrew Cooper
                   ` (5 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Jan Beulich

Future changes will make use of this to advertise availability of levelling
support, and to provide lazy context switching.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
---
 xen/arch/x86/cpu/common.c        |  3 +++
 xen/include/asm-x86/cpufeature.h |  1 +
 xen/include/asm-x86/processor.h  | 15 +++++++++++++++
 3 files changed, 19 insertions(+)

diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c
index 2ad85e0..896a579 100644
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -35,6 +35,9 @@ integer_param("cpuid_mask_ext_edx", opt_cpuid_mask_ext_edx);
 unsigned int __initdata expected_levelling_cap;
 unsigned int __read_mostly levelling_caps;
 
+DEFINE_PER_CPU(struct cpumasks, cpumasks);
+struct cpumasks __read_mostly cpumask_defaults;
+
 const struct cpu_dev *__read_mostly cpu_devs[X86_VENDOR_NUM] = {};
 
 unsigned int paddr_bits __read_mostly = 36;
diff --git a/xen/include/asm-x86/cpufeature.h b/xen/include/asm-x86/cpufeature.h
index 547ed7d..8d48290 100644
--- a/xen/include/asm-x86/cpufeature.h
+++ b/xen/include/asm-x86/cpufeature.h
@@ -111,6 +111,7 @@
 #define cpu_has_xsavec		boot_cpu_has(X86_FEATURE_XSAVEC)
 #define cpu_has_xgetbv1		boot_cpu_has(X86_FEATURE_XGETBV1)
 #define cpu_has_xsaves		boot_cpu_has(X86_FEATURE_XSAVES)
+#define cpu_has_hypervisor	boot_cpu_has(X86_FEATURE_HYPERVISOR)
 
 enum _cache_type {
     CACHE_TYPE_NULL = 0,
diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h
index b2c3653..6d2f09b 100644
--- a/xen/include/asm-x86/processor.h
+++ b/xen/include/asm-x86/processor.h
@@ -585,6 +585,21 @@ int microcode_resume_cpu(unsigned int cpu);
  */
 extern unsigned int expected_levelling_cap, levelling_caps;
 
+struct cpumasks
+{
+    uint64_t _1cd;
+    uint64_t e1cd;
+    uint64_t Da1;
+    uint64_t _6c;
+    uint64_t _7ab0;
+};
+
+/* Per CPU shadows of masking MSR values, for lazy context switching. */
+DECLARE_PER_CPU(struct cpumasks, cpumasks);
+
+/* Default masking MSR values, calculated at boot. */
+extern struct cpumasks cpumask_defaults;
+
 enum get_cpu_vendor {
    gcv_host_early,
    gcv_host_late,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 26/31] xen/x86: Rework AMD masking MSR setup
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (24 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 25/31] xen/x86: Common infrastructure for levelling context switching Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2016-01-22  9:27   ` Jan Beulich
  2015-12-16 21:24 ` [PATCH RFC 27/31] xen/x86: Rework Intel masking/faulting setup Andrew Cooper
                   ` (4 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Jan Beulich

This patch is best reviewed as its end result rather than as a diff, as it
rewrites almost all of the setup.

On the BSP, cpuid information is used to evaluate the potential available set
of masking MSRs, and they are unconditionally probed, filling in the
availability information and hardware defaults.

The command line parameters are then combined with the hardware defaults to
further restrict the Xen default masking level.  Each cpu is then context
switched into the default levelling state.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
---
 xen/arch/x86/cpu/amd.c | 250 ++++++++++++++++++++++++++++++-------------------
 1 file changed, 153 insertions(+), 97 deletions(-)

diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c
index 265fbc0..6b95ab6 100644
--- a/xen/arch/x86/cpu/amd.c
+++ b/xen/arch/x86/cpu/amd.c
@@ -80,6 +80,13 @@ static inline int wrmsr_amd_safe(unsigned int msr, unsigned int lo,
 	return err;
 }
 
+static void wrmsr_amd(unsigned int msr, uint64_t val)
+{
+	asm volatile("wrmsr" ::
+		     "c" (msr), "a" ((uint32_t)val),
+		     "d" (val >> 32), "D" (0x9c5a203a));
+}
+
 static const struct cpuidmask {
 	uint16_t fam;
 	char rev[2];
@@ -126,126 +133,172 @@ static const struct cpuidmask *__init noinline get_cpuidmask(const char *opt)
 }
 
 /*
- * Mask the features and extended features returned by CPUID.  Parameters are
- * set from the boot line via two methods:
- *
- *   1) Specific processor revision string
- *   2) User-defined masks
- *
- * The processor revision string parameter has precedene.
+ * Sets caps in expected_levelling_cap, probes for the specified mask MSR, and
+ * set caps in levelling_caps if it is found.  Processors prior to Fam 10h
+ * required a 32-bit password for masking MSRs.  Reads the default value into
+ * msr_val.
  */
-static void __devinit set_cpuidmask(const struct cpuinfo_x86 *c)
+static void __init __probe_mask_msr(unsigned int msr, uint64_t caps,
+                                    uint64_t *msr_val)
 {
-	static unsigned int feat_ecx, feat_edx;
-	static unsigned int extfeat_ecx, extfeat_edx;
-	static unsigned int l7s0_eax, l7s0_ebx;
-	static unsigned int thermal_ecx;
-	static bool_t skip_feat, skip_extfeat;
-	static bool_t skip_l7s0_eax_ebx, skip_thermal_ecx;
-	static enum { not_parsed, no_mask, set_mask } status;
-	unsigned int eax, ebx, ecx, edx;
-
-	if (status == no_mask)
-		return;
+	unsigned int hi, lo;
+
+        expected_levelling_cap |= caps;
+
+	if ((rdmsr_amd_safe(msr, &lo, &hi) == 0) &&
+	    (wrmsr_amd_safe(msr, lo, hi) == 0))
+		levelling_caps |= caps;
+
+	*msr_val = ((uint64_t)hi << 32) | lo;
+}
 
-	if (status == set_mask)
-		goto setmask;
+/*
+ * Probe for the existance of the expected masking MSRs.  They might easily
+ * not be available if Xen is running virtualised.
+ */
+static void __init noinline probe_masking_msrs(void)
+{
+	const struct cpuinfo_x86 *c = &boot_cpu_data;
 
-	ASSERT((status == not_parsed) && (c == &boot_cpu_data));
-	status = no_mask;
+	/*
+	 * First, work out which masking MSRs we should have, based on
+	 * revision and cpuid.
+	 */
 
 	/* Fam11 doesn't support masking at all. */
 	if (c->x86 == 0x11)
 		return;
 
-	if (~(opt_cpuid_mask_ecx & opt_cpuid_mask_edx &
-	      opt_cpuid_mask_ext_ecx & opt_cpuid_mask_ext_edx &
-	      opt_cpuid_mask_l7s0_eax & opt_cpuid_mask_l7s0_ebx &
-	      opt_cpuid_mask_thermal_ecx)) {
-		feat_ecx = opt_cpuid_mask_ecx;
-		feat_edx = opt_cpuid_mask_edx;
-		extfeat_ecx = opt_cpuid_mask_ext_ecx;
-		extfeat_edx = opt_cpuid_mask_ext_edx;
-		l7s0_eax = opt_cpuid_mask_l7s0_eax;
-		l7s0_ebx = opt_cpuid_mask_l7s0_ebx;
-		thermal_ecx = opt_cpuid_mask_thermal_ecx;
-	} else if (*opt_famrev == '\0') {
+	__probe_mask_msr(MSR_K8_FEATURE_MASK, LCAP_1cd,
+			 &cpumask_defaults._1cd);
+	__probe_mask_msr(MSR_K8_EXT_FEATURE_MASK, LCAP_e1cd,
+			 &cpumask_defaults.e1cd);
+
+	if (c->cpuid_level >= 7)
+		__probe_mask_msr(MSR_AMD_L7S0_FEATURE_MASK, LCAP_7ab0,
+				 &cpumask_defaults._7ab0);
+
+	if (c->x86 == 0x15 && c->cpuid_level >= 6 && cpuid_ecx(6))
+		__probe_mask_msr(MSR_AMD_THRM_FEATURE_MASK, LCAP_6c,
+				 &cpumask_defaults._6c);
+
+	/*
+	 * Don't bother warning about a mismatch if virtualised.  These MSRs
+	 * are not architectural and almost never virtualised.
+	 */
+	if ((expected_levelling_cap == levelling_caps) ||
+	    cpu_has_hypervisor)
 		return;
-	} else {
-		const struct cpuidmask *m = get_cpuidmask(opt_famrev);
+
+	printk(XENLOG_WARNING "Mismatch between expected (%#x"
+	       ") and real (%#x) levelling caps: missing %#x\n",
+	       expected_levelling_cap, levelling_caps,
+	       (expected_levelling_cap ^ levelling_caps) & levelling_caps);
+	printk(XENLOG_WARNING "Fam %#x, model %#x level %#x\n",
+	       c->x86, c->x86_model, c->cpuid_level);
+	printk(XENLOG_WARNING
+	       "If not running virtualised, please report a bug\n");
+}
+
+void amd_ctxt_switch_levelling(const struct domain *nextd)
+{
+	struct cpumasks *these_masks = &this_cpu(cpumasks);
+	const struct cpumasks *masks = &cpumask_defaults;
+
+#define LAZY(cap, msr, field)						\
+	({								\
+		if ( ((levelling_caps & cap) == cap) &&			\
+		     (these_masks->field != masks->field) )		\
+		{							\
+			wrmsr_amd(msr, masks->field);			\
+			these_masks->field = masks->field;		\
+		}							\
+	})
+
+	LAZY(LCAP_1cd,  MSR_K8_FEATURE_MASK,       _1cd);
+	LAZY(LCAP_e1cd, MSR_K8_EXT_FEATURE_MASK,   e1cd);
+	LAZY(LCAP_7ab0, MSR_AMD_L7S0_FEATURE_MASK, _7ab0);
+	LAZY(LCAP_6c,   MSR_AMD_THRM_FEATURE_MASK, _6c);
+
+#undef LAZY
+}
+
+/*
+ * Mask the features and extended features returned by CPUID.  Parameters are
+ * set from the boot line via two methods:
+ *
+ *   1) Specific processor revision string
+ *   2) User-defined masks
+ *
+ * The processor revision string parameter has precedence.
+ */
+static void __init noinline amd_init_levelling(void)
+{
+	const struct cpuidmask *m = NULL;
+
+	probe_masking_msrs();
+
+	if (*opt_famrev != '\0') {
+		m = get_cpuidmask(opt_famrev);
 
 		if (!m) {
 			printk("Invalid processor string: %s\n", opt_famrev);
-			printk("CPUID will not be masked\n");
-			return;
 		}
-		feat_ecx = m->ecx;
-		feat_edx = m->edx;
-		extfeat_ecx = m->ext_ecx;
-		extfeat_edx = m->ext_edx;
 	}
 
-        /* Setting bits in the CPUID mask MSR that are not set in the
-         * unmasked CPUID response can cause those bits to be set in the
-         * masked response.  Avoid that by explicitly masking in software. */
-        feat_ecx &= cpuid_ecx(0x00000001);
-        feat_edx &= cpuid_edx(0x00000001);
-        extfeat_ecx &= cpuid_ecx(0x80000001);
-        extfeat_edx &= cpuid_edx(0x80000001);
+	if ((levelling_caps & LCAP_1cd) == LCAP_1cd) {
+		uint32_t ecx, edx, tmp;
 
-	status = set_mask;
-	printk("Writing CPUID feature mask ECX:EDX -> %08Xh:%08Xh\n", 
-	       feat_ecx, feat_edx);
-	printk("Writing CPUID extended feature mask ECX:EDX -> %08Xh:%08Xh\n", 
-	       extfeat_ecx, extfeat_edx);
+		cpuid(0x00000001, &tmp, &tmp, &ecx, &edx);
 
-	if (c->cpuid_level >= 7)
-		cpuid_count(7, 0, &eax, &ebx, &ecx, &edx);
-	else
-		ebx = eax = 0;
-	if ((eax | ebx) && ~(l7s0_eax & l7s0_ebx)) {
-		if (l7s0_eax > eax)
-			l7s0_eax = eax;
-		l7s0_ebx &= ebx;
-		printk("Writing CPUID leaf 7 subleaf 0 feature mask EAX:EBX -> %08Xh:%08Xh\n",
-		       l7s0_eax, l7s0_ebx);
-	} else
-		skip_l7s0_eax_ebx = 1;
-
-	/* Only Fam15 has the respective MSR. */
-	ecx = c->x86 == 0x15 && c->cpuid_level >= 6 ? cpuid_ecx(6) : 0;
-	if (ecx && ~thermal_ecx) {
-		thermal_ecx &= ecx;
-		printk("Writing CPUID thermal/power feature mask ECX -> %08Xh\n",
-		       thermal_ecx);
-	} else
-		skip_thermal_ecx = 1;
-
- setmask:
-	/* AMD processors prior to family 10h required a 32-bit password */
-	if (!skip_feat &&
-	    wrmsr_amd_safe(MSR_K8_FEATURE_MASK, feat_edx, feat_ecx)) {
-		skip_feat = 1;
-		printk("Failed to set CPUID feature mask\n");
+		if(~(opt_cpuid_mask_ecx & opt_cpuid_mask_edx)) {
+			ecx &= opt_cpuid_mask_ecx;
+			edx &= opt_cpuid_mask_edx;
+		} else if ( m ) {
+			ecx &= m->ecx;
+			edx &= m->edx;
+		}
+
+		cpumask_defaults._1cd = ((uint64_t)ecx << 32) | edx;
 	}
 
-	if (!skip_extfeat &&
-	    wrmsr_amd_safe(MSR_K8_EXT_FEATURE_MASK, extfeat_edx, extfeat_ecx)) {
-		skip_extfeat = 1;
-		printk("Failed to set CPUID extended feature mask\n");
+	if ((levelling_caps & LCAP_e1cd) == LCAP_e1cd) {
+		uint32_t ecx, edx, tmp;
+
+		cpuid(0x80000001, &tmp, &tmp, &ecx, &edx);
+
+		if(~(opt_cpuid_mask_ext_ecx & opt_cpuid_mask_ext_edx)) {
+			ecx &= opt_cpuid_mask_ext_ecx;
+			edx &= opt_cpuid_mask_ext_edx;
+		} else if ( m ) {
+			ecx &= m->ext_ecx;
+			edx &= m->ext_edx;
+		}
+
+		cpumask_defaults.e1cd = ((uint64_t)ecx << 32) | edx;
 	}
 
-	if (!skip_l7s0_eax_ebx &&
-	    wrmsr_amd_safe(MSR_AMD_L7S0_FEATURE_MASK, l7s0_ebx, l7s0_eax)) {
-		skip_l7s0_eax_ebx = 1;
-		printk("Failed to set CPUID leaf 7 subleaf 0 feature mask\n");
+	if ((levelling_caps & LCAP_7ab0) == LCAP_7ab0) {
+		uint32_t eax, ebx, tmp;
+
+		cpuid(0x00000007, &eax, &ebx, &tmp, &tmp);
+
+		if(~(opt_cpuid_mask_l7s0_eax & opt_cpuid_mask_l7s0_ebx)) {
+			eax &= opt_cpuid_mask_l7s0_eax;
+			ebx &= opt_cpuid_mask_l7s0_ebx;
+		}
+
+		cpumask_defaults._7ab0 = ((uint64_t)eax << 32) | ebx;
 	}
 
-	if (!skip_thermal_ecx &&
-	    (rdmsr_amd_safe(MSR_AMD_THRM_FEATURE_MASK, &eax, &edx) ||
-	     wrmsr_amd_safe(MSR_AMD_THRM_FEATURE_MASK, thermal_ecx, edx))){
-		skip_thermal_ecx = 1;
-		printk("Failed to set CPUID thermal/power feature mask\n");
+	if ((levelling_caps & LCAP_6c) == LCAP_6c) {
+		uint32_t ecx = cpuid_ecx(6);
+
+		if (~opt_cpuid_mask_thermal_ecx)
+			ecx &= opt_cpuid_mask_thermal_ecx;
+
+		cpumask_defaults._6c &= (~0ULL << 32);
+		cpumask_defaults._6c |= ecx;
 	}
 }
 
@@ -426,7 +479,10 @@ static void __devinit amd_get_topology(struct cpuinfo_x86 *c)
 
 static void __devinit early_init_amd(struct cpuinfo_x86 *c)
 {
-	set_cpuidmask(c);
+	if (c == &boot_cpu_data)
+		amd_init_levelling();
+
+	amd_ctxt_switch_levelling(NULL);
 }
 
 static void __devinit init_amd(struct cpuinfo_x86 *c)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 27/31] xen/x86: Rework Intel masking/faulting setup
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (25 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 26/31] xen/x86: Rework AMD masking MSR setup Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2016-01-22  9:40   ` Jan Beulich
  2015-12-16 21:24 ` [PATCH RFC 28/31] xen/x86: Context switch all levelling state in context_switch() Andrew Cooper
                   ` (3 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Jan Beulich

This patch is best reviewed as its end result rather than as a diff, as it
rewrites almost all of the setup.

On the BSP, cpuid information is used to evaluate the potential available set
of masking MSRs, and they are unconditionally probed, filling in the
availability information and hardware defaults.  A side effect of this is that
probe_intel_cpuid_faulting() can move to being __init.

The command line parameters are then combined with the hardware defaults to
further restrict the Xen default masking level.  Each cpu is then context
switched into the default levelling state.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
---
 xen/arch/x86/cpu/intel.c | 219 ++++++++++++++++++++++++++++-------------------
 1 file changed, 132 insertions(+), 87 deletions(-)

diff --git a/xen/arch/x86/cpu/intel.c b/xen/arch/x86/cpu/intel.c
index d251b53..f1bb222 100644
--- a/xen/arch/x86/cpu/intel.c
+++ b/xen/arch/x86/cpu/intel.c
@@ -18,11 +18,18 @@
 
 #define select_idle_routine(x) ((void)0)
 
-static unsigned int probe_intel_cpuid_faulting(void)
+static bool_t __init probe_intel_cpuid_faulting(void)
 {
 	uint64_t x;
-	return !rdmsr_safe(MSR_INTEL_PLATFORM_INFO, x) &&
-		(x & MSR_PLATFORM_INFO_CPUID_FAULTING);
+
+	if ( rdmsr_safe(MSR_INTEL_PLATFORM_INFO, x) ||
+	     !(x & MSR_PLATFORM_INFO_CPUID_FAULTING) )
+		return 0;
+
+	expected_levelling_cap |= LCAP_faulting;
+	levelling_caps |=  LCAP_faulting;
+	__set_bit(X86_FEATURE_CPUID_FAULTING, boot_cpu_data.x86_capability);
+	return 1;
 }
 
 static DEFINE_PER_CPU(bool_t, cpuid_faulting_enabled);
@@ -44,41 +51,45 @@ void set_cpuid_faulting(bool_t enable)
 }
 
 /*
- * opt_cpuid_mask_ecx/edx: cpuid.1[ecx, edx] feature mask.
- * For example, E8400[Intel Core 2 Duo Processor series] ecx = 0x0008E3FD,
- * edx = 0xBFEBFBFF when executing CPUID.EAX = 1 normally. If you want to
- * 'rev down' to E8400, you can set these values in these Xen boot parameters.
+ * Set caps in expected_levelling_cap, probe a specific masking MSR, and set
+ * caps in levelling_caps if it is found, or clobber the MSR index if missing.
+ * If preset, reads the default value into msr_val.
  */
-static void __devinit set_cpuidmask(const struct cpuinfo_x86 *c)
+static void __init __probe_mask_msr(unsigned int *msr, uint64_t caps,
+				    uint64_t *msr_val)
 {
-	static unsigned int msr_basic, msr_ext, msr_xsave;
-	static enum { not_parsed, no_mask, set_mask } status;
-	u64 msr_val;
+	uint64_t val;
 
-	if (status == no_mask)
-		return;
+	expected_levelling_cap |= caps;
 
-	if (status == set_mask)
-		goto setmask;
+	if (rdmsr_safe(*msr, val) || wrmsr_safe(*msr, val))
+		*msr = 0;
+	else
+	{
+		levelling_caps |= caps;
+		*msr_val = val;
+	}
+}
 
-	ASSERT((status == not_parsed) && (c == &boot_cpu_data));
-	status = no_mask;
+static unsigned int __read_mostly msr_basic, msr_ext, msr_xsave;
 
-	if (!~(opt_cpuid_mask_ecx & opt_cpuid_mask_edx &
-	       opt_cpuid_mask_ext_ecx & opt_cpuid_mask_ext_edx &
-	       opt_cpuid_mask_xsave_eax))
-		return;
+/*
+ * Probe for the existance of the expected masking MSRs.  They might easily
+ * not be available if Xen is running virtualised.
+ */
+static void __init probe_masking_msrs(void)
+{
+	const struct cpuinfo_x86 *c = &boot_cpu_data;
+	unsigned int exp_msr_basic = 0, exp_msr_ext = 0, exp_msr_xsave = 0;
 
 	/* Only family 6 supports this feature. */
-	if (c->x86 != 6) {
-		printk("No CPUID feature masking support available\n");
+	if (c->x86 != 6)
 		return;
-	}
 
 	switch (c->x86_model) {
 	case 0x17: /* Yorkfield, Wolfdale, Penryn, Harpertown(DP) */
 	case 0x1d: /* Dunnington(MP) */
-		msr_basic = MSR_INTEL_MASK_V1_CPUID1;
+		exp_msr_basic = msr_basic = MSR_INTEL_MASK_V1_CPUID1;
 		break;
 
 	case 0x1a: /* Bloomfield, Nehalem-EP(Gainestown) */
@@ -88,72 +99,115 @@ static void __devinit set_cpuidmask(const struct cpuinfo_x86 *c)
 	case 0x2c: /* Gulftown, Westmere-EP */
 	case 0x2e: /* Nehalem-EX(Beckton) */
 	case 0x2f: /* Westmere-EX */
-		msr_basic = MSR_INTEL_MASK_V2_CPUID1;
-		msr_ext   = MSR_INTEL_MASK_V2_CPUID80000001;
+		exp_msr_basic = msr_basic = MSR_INTEL_MASK_V2_CPUID1;
+		exp_msr_ext   = msr_ext   = MSR_INTEL_MASK_V2_CPUID80000001;
 		break;
 
 	case 0x2a: /* SandyBridge */
 	case 0x2d: /* SandyBridge-E, SandyBridge-EN, SandyBridge-EP */
-		msr_basic = MSR_INTEL_MASK_V3_CPUID1;
-		msr_ext   = MSR_INTEL_MASK_V3_CPUID80000001;
-		msr_xsave = MSR_INTEL_MASK_V3_CPUIDD_01;
+		exp_msr_basic = msr_basic = MSR_INTEL_MASK_V3_CPUID1;
+		exp_msr_ext   = msr_ext   = MSR_INTEL_MASK_V3_CPUID80000001;
+		exp_msr_xsave = msr_xsave = MSR_INTEL_MASK_V3_CPUIDD_01;
 		break;
 	}
 
-	status = set_mask;
+	if (msr_basic)
+		__probe_mask_msr(&msr_basic, LCAP_1cd, &cpumask_defaults._1cd);
+
+	if (msr_ext)
+		__probe_mask_msr(&msr_ext, LCAP_e1cd, &cpumask_defaults.e1cd);
+
+	if (msr_xsave)
+		__probe_mask_msr(&msr_xsave, LCAP_Da1, &cpumask_defaults.Da1);
+
+	/*
+	 * Don't bother warning about a mismatch if virtualised.  These MSRs
+	 * are not architectural and almost never virtualised.
+	 */
+	if ((expected_levelling_cap == levelling_caps) ||
+	    cpu_has_hypervisor)
+		return;
+
+	printk(XENLOG_WARNING "Mismatch between expected (%#x"
+	       ") and real (%#x) levelling caps: missing %#x\n",
+	       expected_levelling_cap, levelling_caps,
+	       (expected_levelling_cap ^ levelling_caps) & levelling_caps);
+	printk(XENLOG_WARNING "Fam %#x, model %#x expected (%#x/%#x/%#x), "
+	       "got (%#x/%#x/%#x)\n", c->x86, c->x86_model,
+	       exp_msr_basic, exp_msr_ext, exp_msr_xsave,
+	       msr_basic, msr_ext, msr_xsave);
+	printk(XENLOG_WARNING
+	       "If not running virtualised, please report a bug\n");
+}
+
+void intel_ctxt_switch_levelling(const struct domain *nextd)
+{
+	struct cpumasks *these_masks = &this_cpu(cpumasks);
+	const struct cpumasks *masks = &cpumask_defaults;
+
+#define LAZY(msr, field)						\
+	({								\
+		if ( msr && (these_masks->field != masks->field) )	\
+		{							\
+			wrmsrl(msr, masks->field);			\
+			these_masks->field = masks->field;		\
+		}							\
+	})
+
+	LAZY(msr_basic, _1cd);
+	LAZY(msr_ext,   e1cd);
+	LAZY(msr_xsave, Da1);
+
+#undef LAZY
+}
 
-	if (~(opt_cpuid_mask_ecx & opt_cpuid_mask_edx)) {
-		if (msr_basic)
+/*
+ * opt_cpuid_mask_ecx/edx: cpuid.1[ecx, edx] feature mask.
+ * For example, E8400[Intel Core 2 Duo Processor series] ecx = 0x0008E3FD,
+ * edx = 0xBFEBFBFF when executing CPUID.EAX = 1 normally. If you want to
+ * 'rev down' to E8400, you can set these values in these Xen boot parameters.
+ */
+static void __init noinline intel_init_levelling(void)
+{
+	if ( !probe_intel_cpuid_faulting() )
+		probe_masking_msrs();
+
+	if ( msr_basic )
+	{
+		cpumask_defaults._1cd =
+			((u64)opt_cpuid_mask_edx << 32) | opt_cpuid_mask_ecx;
+
+		if ( !~(opt_cpuid_mask_ecx & opt_cpuid_mask_edx) )
 			printk("Writing CPUID feature mask ecx:edx -> %08x:%08x\n",
 			       opt_cpuid_mask_ecx, opt_cpuid_mask_edx);
-		else
-			printk("No CPUID feature mask available\n");
 	}
-	else
-		msr_basic = 0;
+	else if ( !~(opt_cpuid_mask_ecx & opt_cpuid_mask_edx) )
+		printk("No CPUID feature mask available\n");
+
+	if ( msr_ext )
+	{
+		cpumask_defaults.e1cd =
+			((u64)opt_cpuid_mask_ext_edx << 32) |
+			opt_cpuid_mask_ext_ecx;
 
-	if (~(opt_cpuid_mask_ext_ecx & opt_cpuid_mask_ext_edx)) {
-		if (msr_ext)
+		if ( !~(opt_cpuid_mask_ext_ecx & opt_cpuid_mask_ext_edx) )
 			printk("Writing CPUID extended feature mask ecx:edx -> %08x:%08x\n",
 			       opt_cpuid_mask_ext_ecx, opt_cpuid_mask_ext_edx);
-		else
-			printk("No CPUID extended feature mask available\n");
 	}
-	else
-		msr_ext = 0;
+	else if ( !~(opt_cpuid_mask_ext_ecx & opt_cpuid_mask_ext_edx) )
+		printk("No CPUID extended feature mask available\n");
+
+	if ( msr_xsave )
+	{
+		cpumask_defaults.Da1 &= (~0ULL << 32);
+		cpumask_defaults.Da1 |= opt_cpuid_mask_xsave_eax;
 
-	if (~opt_cpuid_mask_xsave_eax) {
-		if (msr_xsave)
+		if ( !~opt_cpuid_mask_xsave_eax )
 			printk("Writing CPUID xsave feature mask eax -> %08x\n",
 			       opt_cpuid_mask_xsave_eax);
-		else
-			printk("No CPUID xsave feature mask available\n");
-	}
-	else
-		msr_xsave = 0;
-
- setmask:
-	if (msr_basic &&
-	    wrmsr_safe(msr_basic,
-		       ((u64)opt_cpuid_mask_edx << 32) | opt_cpuid_mask_ecx)){
-		msr_basic = 0;
-		printk("Failed to set CPUID feature mask\n");
-	}
-
-	if (msr_ext &&
-	    wrmsr_safe(msr_ext,
-		       ((u64)opt_cpuid_mask_ext_edx << 32) | opt_cpuid_mask_ext_ecx)){
-		msr_ext = 0;
-		printk("Failed to set CPUID extended feature mask\n");
-	}
-
-	if (msr_xsave &&
-	    (rdmsr_safe(msr_xsave, msr_val) ||
-	     wrmsr_safe(msr_xsave,
-			(msr_val & (~0ULL << 32)) | opt_cpuid_mask_xsave_eax))){
-		msr_xsave = 0;
-		printk("Failed to set CPUID xsave feature mask\n");
 	}
+	else if ( !~opt_cpuid_mask_xsave_eax )
+		printk("No CPUID xsave feature mask available\n");
 }
 
 static void early_init_intel(struct cpuinfo_x86 *c)
@@ -183,22 +237,13 @@ static void early_init_intel(struct cpuinfo_x86 *c)
 	    (boot_cpu_data.x86_mask == 3 || boot_cpu_data.x86_mask == 4))
 		paddr_bits = 36;
 
-	if (c == &boot_cpu_data && c->x86 == 6) {
-		if (probe_intel_cpuid_faulting())
-			__set_bit(X86_FEATURE_CPUID_FAULTING,
-				  c->x86_capability);
-	} else if (boot_cpu_has(X86_FEATURE_CPUID_FAULTING)) {
-		BUG_ON(!probe_intel_cpuid_faulting());
-		__set_bit(X86_FEATURE_CPUID_FAULTING, c->x86_capability);
-	}
+	if (c == &boot_cpu_data)
+		intel_init_levelling();
+
+	if (test_bit(X86_FEATURE_CPUID_FAULTING, boot_cpu_data.x86_capability))
+            __set_bit(X86_FEATURE_CPUID_FAULTING, c->x86_capability);
 
-	if (!cpu_has_cpuid_faulting)
-		set_cpuidmask(c);
-	else if ((c == &boot_cpu_data) &&
-		 (~(opt_cpuid_mask_ecx & opt_cpuid_mask_edx &
-		    opt_cpuid_mask_ext_ecx & opt_cpuid_mask_ext_edx &
-		    opt_cpuid_mask_xsave_eax)))
-		printk("No CPUID feature masking support available\n");
+	intel_ctxt_switch_levelling(NULL);
 }
 
 /*
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 28/31] xen/x86: Context switch all levelling state in context_switch()
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (26 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 27/31] xen/x86: Rework Intel masking/faulting setup Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2016-01-22  9:52   ` Jan Beulich
  2015-12-16 21:24 ` [PATCH RFC 29/31] x86/pv: Provide custom cpumasks for PV domains Andrew Cooper
                   ` (2 subsequent siblings)
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Jan Beulich

A single ctxt_switch_levelling() function pointer is provided
(defaulting to an empty nop), which is overridden in the appropriate
$VENDOR_init_levelling().

set_cpuid_faulting() is made private and included within
intel_ctxt_switch_levelling()

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
---
 xen/arch/x86/cpu/amd.c          |  3 +++
 xen/arch/x86/cpu/common.c       |  7 +++++++
 xen/arch/x86/cpu/intel.c        | 14 ++++++++++++--
 xen/arch/x86/domain.c           |  4 +---
 xen/include/asm-x86/processor.h |  2 +-
 5 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c
index 6b95ab6..cc1344a 100644
--- a/xen/arch/x86/cpu/amd.c
+++ b/xen/arch/x86/cpu/amd.c
@@ -300,6 +300,9 @@ static void __init noinline amd_init_levelling(void)
 		cpumask_defaults._6c &= (~0ULL << 32);
 		cpumask_defaults._6c |= ecx;
 	}
+
+        if (levelling_caps)
+            ctxt_switch_levelling = amd_ctxt_switch_levelling;
 }
 
 /*
diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c
index 896a579..4802ce8 100644
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -86,6 +86,13 @@ static const struct cpu_dev default_cpu = {
 };
 static const struct cpu_dev *this_cpu = &default_cpu;
 
+void default_ctxt_switch_levelling(const struct domain *nextd)
+{
+    /* Nop */
+}
+void (*ctxt_switch_levelling)(const struct domain *nextd) __read_mostly =
+    default_ctxt_switch_levelling;
+
 bool_t opt_cpu_info;
 boolean_param("cpuinfo", opt_cpu_info);
 
diff --git a/xen/arch/x86/cpu/intel.c b/xen/arch/x86/cpu/intel.c
index f1bb222..87c66d2 100644
--- a/xen/arch/x86/cpu/intel.c
+++ b/xen/arch/x86/cpu/intel.c
@@ -32,9 +32,9 @@ static bool_t __init probe_intel_cpuid_faulting(void)
 	return 1;
 }
 
-static DEFINE_PER_CPU(bool_t, cpuid_faulting_enabled);
-void set_cpuid_faulting(bool_t enable)
+static void set_cpuid_faulting(bool_t enable)
 {
+	static DEFINE_PER_CPU(bool_t, cpuid_faulting_enabled);
 	uint32_t hi, lo;
 
 	if (!cpu_has_cpuid_faulting ||
@@ -145,6 +145,13 @@ void intel_ctxt_switch_levelling(const struct domain *nextd)
 	struct cpumasks *these_masks = &this_cpu(cpumasks);
 	const struct cpumasks *masks = &cpumask_defaults;
 
+	if (cpu_has_cpuid_faulting) {
+		set_cpuid_faulting(nextd && is_pv_domain(nextd) &&
+				   !is_control_domain(nextd) &&
+				   !is_hardware_domain(nextd));
+		return;
+	}
+
 #define LAZY(msr, field)						\
 	({								\
 		if ( msr && (these_masks->field != masks->field) )	\
@@ -208,6 +215,9 @@ static void __init noinline intel_init_levelling(void)
 	}
 	else if ( !~opt_cpuid_mask_xsave_eax )
 		printk("No CPUID xsave feature mask available\n");
+
+	if (levelling_caps)
+		ctxt_switch_levelling = intel_ctxt_switch_levelling;
 }
 
 static void early_init_intel(struct cpuinfo_x86 *c)
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index 51adb8d..e9f1af1 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -1639,9 +1639,7 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
             load_segments(next);
         }
 
-        set_cpuid_faulting(is_pv_domain(nextd) &&
-                           !is_control_domain(nextd) &&
-                           !is_hardware_domain(nextd));
+        ctxt_switch_levelling(nextd);
     }
 
     context_saved(prev);
diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h
index 6d2f09b..52e5eae 100644
--- a/xen/include/asm-x86/processor.h
+++ b/xen/include/asm-x86/processor.h
@@ -204,7 +204,7 @@ extern struct cpuinfo_x86 boot_cpu_data;
 extern struct cpuinfo_x86 cpu_data[];
 #define current_cpu_data cpu_data[smp_processor_id()]
 
-extern void set_cpuid_faulting(bool_t enable);
+extern void (*ctxt_switch_levelling)(const struct domain *nextd);
 
 extern u64 host_pat;
 extern bool_t opt_cpu_info;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 29/31] x86/pv: Provide custom cpumasks for PV domains
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (27 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 28/31] xen/x86: Context switch all levelling state in context_switch() Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2016-01-22  9:56   ` Jan Beulich
  2015-12-16 21:24 ` [PATCH RFC 30/31] x86/domctl: Update PV domain cpumasks when setting cpuid policy Andrew Cooper
  2015-12-16 21:24 ` [PATCH RFC 31/31] tools/libxc: Calculate xstate cpuid leaf from guest information Andrew Cooper
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Jan Beulich

And use them in preference to cpumask_defaults on context switch.  HVM domains
must not be masked (to avoid interfering with cpuid calls within the guest),
so always lazily context switch to the host default.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
---
 xen/arch/x86/cpu/amd.c       | 4 +++-
 xen/arch/x86/cpu/intel.c     | 5 ++++-
 xen/arch/x86/domain.c        | 9 +++++++++
 xen/include/asm-x86/domain.h | 2 ++
 4 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/cpu/amd.c b/xen/arch/x86/cpu/amd.c
index cc1344a..a925614 100644
--- a/xen/arch/x86/cpu/amd.c
+++ b/xen/arch/x86/cpu/amd.c
@@ -203,7 +203,9 @@ static void __init noinline probe_masking_msrs(void)
 void amd_ctxt_switch_levelling(const struct domain *nextd)
 {
 	struct cpumasks *these_masks = &this_cpu(cpumasks);
-	const struct cpumasks *masks = &cpumask_defaults;
+	const struct cpumasks *masks =
+            (nextd && is_pv_domain(nextd) && nextd->arch.pv_domain.masks)
+            ? nextd->arch.pv_domain.masks : &cpumask_defaults;
 
 #define LAZY(cap, msr, field)						\
 	({								\
diff --git a/xen/arch/x86/cpu/intel.c b/xen/arch/x86/cpu/intel.c
index 87c66d2..5d2ce3f 100644
--- a/xen/arch/x86/cpu/intel.c
+++ b/xen/arch/x86/cpu/intel.c
@@ -143,7 +143,7 @@ static void __init probe_masking_msrs(void)
 void intel_ctxt_switch_levelling(const struct domain *nextd)
 {
 	struct cpumasks *these_masks = &this_cpu(cpumasks);
-	const struct cpumasks *masks = &cpumask_defaults;
+	const struct cpumasks *masks;
 
 	if (cpu_has_cpuid_faulting) {
 		set_cpuid_faulting(nextd && is_pv_domain(nextd) &&
@@ -152,6 +152,9 @@ void intel_ctxt_switch_levelling(const struct domain *nextd)
 		return;
 	}
 
+	masks = (nextd && is_pv_domain(nextd) && nextd->arch.pv_domain.masks)
+		? nextd->arch.pv_domain.masks : &cpumask_defaults;
+
 #define LAZY(msr, field)						\
 	({								\
 		if ( msr && (these_masks->field != masks->field) )	\
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index e9f1af1..84fd74b 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -578,6 +578,12 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
             goto fail;
         clear_page(d->arch.pv_domain.gdt_ldt_l1tab);
 
+        d->arch.pv_domain.masks = xmalloc(struct cpumasks);
+        if ( !d->arch.pv_domain.masks )
+            goto fail;
+        memcpy(d->arch.pv_domain.masks, &cpumask_defaults,
+               sizeof(*d->arch.pv_domain.masks));
+
         rc = create_perdomain_mapping(d, GDT_LDT_VIRT_START,
                                       GDT_LDT_MBYTES << (20 - PAGE_SHIFT),
                                       NULL, NULL);
@@ -690,7 +696,10 @@ void arch_domain_destroy(struct domain *d)
 
     free_perdomain_mappings(d);
     if ( is_pv_domain(d) )
+    {
         free_xenheap_page(d->arch.pv_domain.gdt_ldt_l1tab);
+        xfree(d->arch.pv_domain.masks);
+    }
 
     free_xenheap_page(d->shared_info);
     cleanup_domain_irq_mapping(d);
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index 0fce09e..dbed9ed 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -249,6 +249,8 @@ struct pv_domain
 
     /* map_domain_page() mapping cache. */
     struct mapcache_domain mapcache;
+
+    struct cpumasks *masks;
 };
 
 struct monitor_write_data {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 30/31] x86/domctl: Update PV domain cpumasks when setting cpuid policy
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (28 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 29/31] x86/pv: Provide custom cpumasks for PV domains Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  2016-01-22 10:02   ` Jan Beulich
  2015-12-16 21:24 ` [PATCH RFC 31/31] tools/libxc: Calculate xstate cpuid leaf from guest information Andrew Cooper
  30 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Jan Beulich

This allows PV domains with different featuresets to observe different values
from a native cpuid instruction, on supporting hardware.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Jan Beulich <JBeulich@suse.com>
---
 xen/arch/x86/domctl.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index 5eb8f00..967e8e7 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -77,6 +77,74 @@ static void update_domain_cpuid_info(struct domain *d,
         d->arch.x86_model = (ctl->eax >> 4) & 0xf;
         if ( d->arch.x86 >= 0x6 )
             d->arch.x86_model |= (ctl->eax >> 12) & 0xf0;
+
+        if ( is_pv_domain(d) )
+        {
+            uint64_t mask = cpumask_defaults._1cd;
+
+            if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
+                mask &= ((uint64_t)ctl->edx << 32) | ctl->ecx;
+            else if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
+                mask &= ((uint64_t)ctl->ecx << 32) | ctl->edx;
+
+            d->arch.pv_domain.masks->_1cd = mask;
+        }
+        break;
+
+    case 6:
+        if ( is_pv_domain(d) )
+        {
+            uint64_t mask = cpumask_defaults._6c;
+
+            if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
+                mask &= ((~0ULL << 32) | ctl->ecx);
+
+            d->arch.pv_domain.masks->_6c = mask;
+        }
+        break;
+
+    case 7:
+        if ( ctl->input[1] != 0 )
+            break;
+
+        if ( is_pv_domain(d) )
+        {
+            uint64_t mask = cpumask_defaults._7ab0;
+
+            if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
+                mask &= ((uint64_t)ctl->eax << 32) | ctl->ebx;
+
+            d->arch.pv_domain.masks->_7ab0 = mask;
+        }
+        break;
+
+    case 0xd:
+        if ( ctl->input[1] != 1 )
+            break;
+
+        if ( is_pv_domain(d) )
+        {
+            uint64_t mask = cpumask_defaults.Da1;
+
+            if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
+                mask &= ((~0ULL << 32) | ctl->eax);
+
+            d->arch.pv_domain.masks->Da1 = mask;
+        }
+        break;
+
+    case 0x80000001:
+        if ( is_pv_domain(d) )
+        {
+            uint64_t mask = cpumask_defaults.e1cd;
+
+            if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
+                mask &= ((uint64_t)ctl->edx << 32) | ctl->ecx;
+            else if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
+                mask &= ((uint64_t)ctl->ecx << 32) | ctl->edx;
+
+            d->arch.pv_domain.masks->e1cd = mask;
+        }
         break;
     }
 }
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* [PATCH RFC 31/31] tools/libxc: Calculate xstate cpuid leaf from guest information
  2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
                   ` (29 preceding siblings ...)
  2015-12-16 21:24 ` [PATCH RFC 30/31] x86/domctl: Update PV domain cpumasks when setting cpuid policy Andrew Cooper
@ 2015-12-16 21:24 ` Andrew Cooper
  30 siblings, 0 replies; 123+ messages in thread
From: Andrew Cooper @ 2015-12-16 21:24 UTC (permalink / raw)
  To: Xen-devel; +Cc: Andrew Cooper, Ian Jackson, Ian Campbell, Wei Liu

It is unsafe to generate the guests xstate leaves from host information, as it
prevents the differences between hosts from being hidden.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
---
CC: Ian Campbell <Ian.Campbell@citrix.com>
CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
CC: Wei Liu <wei.liu2@citrix.com>
---
 tools/libxc/xc_cpuid_x86.c | 44 ++++++++++++++++++++++++++++++++++----------
 1 file changed, 34 insertions(+), 10 deletions(-)

diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
index 6c8995f..9c1d30d 100644
--- a/tools/libxc/xc_cpuid_x86.c
+++ b/tools/libxc/xc_cpuid_x86.c
@@ -285,40 +285,64 @@ static void intel_xc_cpuid_policy(xc_interface *xch,
     }
 }
 
+#define X86_XCR0_X87    (1ULL <<  0)
+#define X86_XCR0_SSE    (1ULL <<  1)
+#define X86_XCR0_AVX    (1ULL <<  2)
+#define X86_XCR0_LWP    (1ULL << 62)
+
 #define XSAVEOPT        (1 << 0)
 /* Configure extended state enumeration leaves (0x0000000D for xsave) */
 static void xc_cpuid_config_xsave(xc_interface *xch,
                                   const struct cpuid_domain_info *info,
                                   const unsigned int *input, unsigned int *regs)
 {
-    if ( info->xfeature_mask == 0 )
+    uint64_t guest_xfeature_mask;
+
+    if ( info->xfeature_mask == 0 ||
+         !test_bit(X86_FEATURE_XSAVE, info->featureset) )
     {
         regs[0] = regs[1] = regs[2] = regs[3] = 0;
         return;
     }
 
+    guest_xfeature_mask = X86_XCR0_SSE | X86_XCR0_X87;
+
+    if ( test_bit(X86_FEATURE_AVX, info->featureset) )
+        guest_xfeature_mask |= X86_XCR0_AVX;
+
+    if ( test_bit(X86_FEATURE_LWP, info->featureset) )
+        guest_xfeature_mask |= X86_XCR0_LWP;
+
+    /*
+     * Clamp to host mask.  Should be no-op, as guest_xfeature_mask should not
+     * be able to be calculated as larger than info->xfeature_mask.
+     *
+     * TODO - see about making this a harder error.
+     */
+    guest_xfeature_mask &= info->xfeature_mask;
+
     switch ( input[1] )
     {
-    case 0: 
+    case 0:
         /* EAX: low 32bits of xfeature_enabled_mask */
-        regs[0] = info->xfeature_mask & 0xFFFFFFFF;
+        regs[0] = guest_xfeature_mask & 0xFFFFFFFF;
         /* EDX: high 32bits of xfeature_enabled_mask */
-        regs[3] = (info->xfeature_mask >> 32) & 0xFFFFFFFF;
+        regs[3] = (guest_xfeature_mask >> 32) & 0xFFFFFFFF;
         /* ECX: max size required by all HW features */
         {
             unsigned int _input[2] = {0xd, 0x0}, _regs[4];
             regs[2] = 0;
-            for ( _input[1] = 2; _input[1] < 64; _input[1]++ )
+            for ( _input[1] = 2; _input[1] <= 62; _input[1]++ )
             {
                 cpuid(_input, _regs);
                 if ( (_regs[0] + _regs[1]) > regs[2] )
                     regs[2] = _regs[0] + _regs[1];
             }
         }
-        /* EBX: max size required by enabled features. 
-         * This register contains a dynamic value, which varies when a guest 
-         * enables or disables XSTATE features (via xsetbv). The default size 
-         * after reset is 576. */ 
+        /* EBX: max size required by enabled features.
+         * This register contains a dynamic value, which varies when a guest
+         * enables or disables XSTATE features (via xsetbv). The default size
+         * after reset is 576. */
         regs[1] = 512 + 64; /* FP/SSE + XSAVE.HEADER */
         break;
     case 1: /* leaf 1 */
@@ -326,7 +350,7 @@ static void xc_cpuid_config_xsave(xc_interface *xch,
         regs[1] = regs[2] = regs[3] = 0;
         break;
     case 2 ... 63: /* sub-leaves */
-        if ( !(info->xfeature_mask & (1ULL << input[1])) )
+        if ( !(guest_xfeature_mask & (1ULL << input[1])) )
         {
             regs[0] = regs[1] = regs[2] = regs[3] = 0;
             break;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 01/31] xen/public: Export featureset information in the public API
  2015-12-16 21:24 ` [PATCH RFC 01/31] xen/public: Export featureset information in the public API Andrew Cooper
@ 2015-12-22 16:28   ` Jan Beulich
  2015-12-22 16:42     ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Jan Beulich @ 2015-12-22 16:28 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Tim Deegan, Ian Campbell, Xen-devel

>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
> +/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, FSMAX+2 */
> +#define X86_FEATURE_XSTORE	((FSMAX+1)*32+ 2) /* on-CPU RNG present (xstore insn) */
> +#define X86_FEATURE_XSTORE_EN	((FSMAX+1)*32+ 3) /* on-CPU RNG enabled */
> +#define X86_FEATURE_XCRYPT	((FSMAX+1)*32+ 6) /* on-CPU crypto (xcrypt insn) */
> +#define X86_FEATURE_XCRYPT_EN	((FSMAX+1)*32+ 7) /* on-CPU crypto enabled */
> +#define X86_FEATURE_ACE2	((FSMAX+1)*32+ 8) /* Advanced Cryptography Engine v2 */
> +#define X86_FEATURE_ACE2_EN	((FSMAX+1)*32+ 9) /* ACE v2 enabled */
> +#define X86_FEATURE_PHE		((FSMAX+1)*32+10) /* PadLock Hash Engine */
> +#define X86_FEATURE_PHE_EN	((FSMAX+1)*32+11) /* PHE enabled */
> +#define X86_FEATURE_PMM		((FSMAX+1)*32+12) /* PadLock Montgomery Multiplier */
> +#define X86_FEATURE_PMM_EN	((FSMAX+1)*32+13) /* PMM enabled */

None of these get consumed anywhere - if you already touch this
code, just drop all of them.

> +/*
> + * CPUID leaf shorthand:
> + * - optional 'e', Extended (0x8xxxxxxx)
> + * - leaf, uppercase hex
> + * - register, lowercase
> + * - optional subleaf, uppercase hex
> + */
> +#define XEN_FEATURESET_1d     0 /* 0x00000001.edx      */
> +#define XEN_FEATURESET_1c     1 /* 0x00000001.ecx      */
> +#define XEN_FEATURESET_e1d    2 /* 0x80000001.edx      */
> +#define XEN_FEATURESET_e1c    3 /* 0x80000001.ecx      */
> +#define XEN_FEATURESET_Da1    4 /* 0x0000000d:1.eax    */
> +#define XEN_FEATURESET_7b0    5 /* 0x00000007:0.ebx    */

This ends up being pretty cryptic.

> +#define XEN_NR_FEATURESET_ENTRIES (XEN_FEATURESET_7b0 + 1)

This shouldn't be exposed, as it will necessarily change sooner or later.

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 02/31] tools/libxc: Use public/featureset.h for cpuid policy generation
  2015-12-16 21:24 ` [PATCH RFC 02/31] tools/libxc: Use public/featureset.h for cpuid policy generation Andrew Cooper
@ 2015-12-22 16:29   ` Jan Beulich
  2016-01-05 14:13     ` Ian Campbell
  0 siblings, 1 reply; 123+ messages in thread
From: Jan Beulich @ 2015-12-22 16:29 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Tim Deegan, Ian Jackson, Ian Campbell, Xen-devel

>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
> --- a/xen/include/public/arch-x86/featureset.h
> +++ b/xen/include/public/arch-x86/featureset.h
> @@ -163,6 +163,7 @@
>  
>  /* Intel-defined CPU features, CPUID level 0x00000007:0.ebx, word 5 */
>  #define X86_FEATURE_FSGSBASE      ( 5*32+ 0) /* {RD,WR}{FS,GS}BASE instructions */
> +#define X86_FEATURE_TSC_ADJUST    ( 5*32+ 1) /* TSC_ADJUST MSR available */

This would probably better go into patch 1.

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 03/31] xen/x86: Store antifeatures inverted in a featureset
  2015-12-16 21:24 ` [PATCH RFC 03/31] xen/x86: Store antifeatures inverted in a featureset Andrew Cooper
@ 2015-12-22 16:32   ` Jan Beulich
  2015-12-22 17:03     ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Jan Beulich @ 2015-12-22 16:32 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
> --- /dev/null
> +++ b/xen/arch/x86/cpuid/cpuid-private.h
> @@ -0,0 +1,27 @@
> +#ifdef __XEN__
> +
> +#include <asm/cpufeature.h>
> +
> +#include <xen/lib.h>
> +
> +#else
> +
> +# error TODO for userspace

I suppose your intentions with this will become apparent in later
patches?

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 04/31] xen/x86: Mask out unknown features from Xen's capabilities
  2015-12-16 21:24 ` [PATCH RFC 04/31] xen/x86: Mask out unknown features from Xen's capabilities Andrew Cooper
@ 2015-12-22 16:42   ` Jan Beulich
  2015-12-22 17:01     ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Jan Beulich @ 2015-12-22 16:42 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
> --- a/xen/arch/x86/cpu/common.c
> +++ b/xen/arch/x86/cpu/common.c
> @@ -324,6 +324,7 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
>  	 * we do "generic changes."
>  	 */
>  	for (i = 0; i < XEN_NR_FEATURESET_ENTRIES; ++i) {
> +		c->x86_capability[i] &= known_features[i];
>  		c->x86_capability[i] ^= inverted_features[i];
>  	}

Assert that no unknown features slipped into the inverted ones?
But see also below.

> --- a/xen/arch/x86/cpuid/cpuid-private.h
> +++ b/xen/arch/x86/cpuid/cpuid-private.h
> @@ -10,6 +10,32 @@
>  
>  #endif
>  
> +/* Mask of bits which are shared between 1d and e1d. */
> +#define SHARED_1d                               \
> +    (cpufeat_mask(X86_FEATURE_FPU)   |          \
> +     cpufeat_mask(X86_FEATURE_VME)   |          \
> +     cpufeat_mask(X86_FEATURE_DE)    |          \
> +     cpufeat_mask(X86_FEATURE_PSE)   |          \
> +     cpufeat_mask(X86_FEATURE_TSC)   |          \
> +     cpufeat_mask(X86_FEATURE_MSR)   |          \
> +     cpufeat_mask(X86_FEATURE_PAE)   |          \
> +     cpufeat_mask(X86_FEATURE_MCE)   |          \
> +     cpufeat_mask(X86_FEATURE_CX8)   |          \
> +     cpufeat_mask(X86_FEATURE_APIC)  |          \
> +     cpufeat_mask(X86_FEATURE_MTRR)  |          \
> +     cpufeat_mask(X86_FEATURE_PGE)   |          \
> +     cpufeat_mask(X86_FEATURE_MCA)   |          \
> +     cpufeat_mask(X86_FEATURE_CMOV)  |          \
> +     cpufeat_mask(X86_FEATURE_PAT)   |          \
> +     cpufeat_mask(X86_FEATURE_PSE36) |          \
> +     cpufeat_mask(X86_FEATURE_MMX)   |          \
> +     cpufeat_mask(X86_FEATURE_FXSR))

These are shared for AMD, but zero in the extended leaf for Intel.

> --- a/xen/arch/x86/cpuid/cpuid.c
> +++ b/xen/arch/x86/cpuid/cpuid.c
> @@ -1,5 +1,110 @@
>  #include "cpuid-private.h"
>  
> +const uint32_t known_features[XEN_NR_FEATURESET_ENTRIES] =
> +{
> +    [cpufeat_word(X86_FEATURE_FPU)] = (SHARED_1d                           |
> +                                       cpufeat_mask(X86_FEATURE_SEP)       |

I can see how you try to remove fixed relationship, but using
FPU in the array index when no FPU appear in the list is at
least confusing.

Looking at the rest, adding a new feature will become quite a bit
more involved. I think we need some better abstraction here, e.g.
a mechanism similar to the one I used in public/errno.h or the one
Linux uses to populate its syscall tables or /proc/cpuinfo's feature
list to allow multiple inclusion of a single list of definitions where all
properties of each individual feature are maintained on one line.

The tables in this file would then be derived from this (perhaps
via further steps of machine processing).

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 01/31] xen/public: Export featureset information in the public API
  2015-12-22 16:28   ` Jan Beulich
@ 2015-12-22 16:42     ` Andrew Cooper
  2015-12-22 16:59       ` Jan Beulich
  0 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-22 16:42 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Tim Deegan, Ian Campbell, Xen-devel

On 22/12/15 16:28, Jan Beulich wrote:
>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>> +/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, FSMAX+2 */
>> +#define X86_FEATURE_XSTORE	((FSMAX+1)*32+ 2) /* on-CPU RNG present (xstore insn) */
>> +#define X86_FEATURE_XSTORE_EN	((FSMAX+1)*32+ 3) /* on-CPU RNG enabled */
>> +#define X86_FEATURE_XCRYPT	((FSMAX+1)*32+ 6) /* on-CPU crypto (xcrypt insn) */
>> +#define X86_FEATURE_XCRYPT_EN	((FSMAX+1)*32+ 7) /* on-CPU crypto enabled */
>> +#define X86_FEATURE_ACE2	((FSMAX+1)*32+ 8) /* Advanced Cryptography Engine v2 */
>> +#define X86_FEATURE_ACE2_EN	((FSMAX+1)*32+ 9) /* ACE v2 enabled */
>> +#define X86_FEATURE_PHE		((FSMAX+1)*32+10) /* PadLock Hash Engine */
>> +#define X86_FEATURE_PHE_EN	((FSMAX+1)*32+11) /* PHE enabled */
>> +#define X86_FEATURE_PMM		((FSMAX+1)*32+12) /* PadLock Montgomery Multiplier */
>> +#define X86_FEATURE_PMM_EN	((FSMAX+1)*32+13) /* PMM enabled */
> None of these get consumed anywhere - if you already touch this
> code, just drop all of them.

X86_FEATURE_XSTORE gets used in xen/arch/x86/cpu/centaur.c to stash word
0xC0000001, but nothing actually reads the stashed values.

I could do a precursor patch which drops the stashing of this
information, which will result in NCAPINTS getting shorter by the end of
the series.

>
>> +/*
>> + * CPUID leaf shorthand:
>> + * - optional 'e', Extended (0x8xxxxxxx)
>> + * - leaf, uppercase hex
>> + * - register, lowercase
>> + * - optional subleaf, uppercase hex
>> + */
>> +#define XEN_FEATURESET_1d     0 /* 0x00000001.edx      */
>> +#define XEN_FEATURESET_1c     1 /* 0x00000001.ecx      */
>> +#define XEN_FEATURESET_e1d    2 /* 0x80000001.edx      */
>> +#define XEN_FEATURESET_e1c    3 /* 0x80000001.ecx      */
>> +#define XEN_FEATURESET_Da1    4 /* 0x0000000d:1.eax    */
>> +#define XEN_FEATURESET_7b0    5 /* 0x00000007:0.ebx    */
> This ends up being pretty cryptic.

Perhaps at a first glance, but there are so many uses that a shorthand
really is needed.  See especially the MSR masking patches towards the
end of the series.

>
>> +#define XEN_NR_FEATURESET_ENTRIES (XEN_FEATURESET_7b0 + 1)
> This shouldn't be exposed, as it will necessarily change sooner or later.

Hmm yes - I think I can alter where this lives, although libxc does need
to be able to get this value.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 05/31] xen/x86: Collect more CPUID feature words
  2015-12-16 21:24 ` [PATCH RFC 05/31] xen/x86: Collect more CPUID feature words Andrew Cooper
@ 2015-12-22 16:46   ` Jan Beulich
  2015-12-22 17:17     ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Jan Beulich @ 2015-12-22 16:46 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
> --- a/xen/arch/x86/cpu/amd.c
> +++ b/xen/arch/x86/cpu/amd.c
> @@ -481,7 +481,7 @@ static void __devinit init_amd(struct cpuinfo_x86 *c)
>  
>  	if (c->extended_cpuid_level >= 0x80000007) {
>  		c->x86_power = cpuid_edx(0x80000007);
> -		if (c->x86_power & (1<<8)) {
> +		if (c->x86_power & cpufeat_mask(X86_FEATURE_ITSC)) {

generic_identify() has already run by the time we get here, so no
need to re-read cpuid_edx() (interestingly enough you leverage
this in init_intel()).

> --- a/xen/arch/x86/cpuid/cpuid.c
> +++ b/xen/arch/x86/cpuid/cpuid.c
> @@ -103,6 +103,12 @@ const uint32_t known_features[XEN_NR_FEATURESET_ENTRIES] =
>                                              cpufeat_mask(X86_FEATURE_RDSEED)     |
>                                              cpufeat_mask(X86_FEATURE_ADX)        |
>                                              cpufeat_mask(X86_FEATURE_SMAP)),
> +
> +    [cpufeat_word(X86_FEATURE_PREFETCHWT1)] = (cpufeat_mask(X86_FEATURE_PREFETCHWT1)),
> +
> +    [cpufeat_word(X86_FEATURE_ITSC)] = (cpufeat_mask(X86_FEATURE_ITSC)),
> +
> +    [cpufeat_word(X86_FEATURE_CLZERO)] = (cpufeat_mask(X86_FEATURE_CLZERO)),
>  };

Are these indeed the only ones in their groups that can be safely
marked "known"?

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 06/31] xen/x86: Infrastructure to calculate guest featuresets
  2015-12-16 21:24 ` [PATCH RFC 06/31] xen/x86: Infrastructure to calculate guest featuresets Andrew Cooper
@ 2015-12-22 16:50   ` Jan Beulich
  0 siblings, 0 replies; 123+ messages in thread
From: Jan Beulich @ 2015-12-22 16:50 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>  xen/arch/x86/Makefile       |  1 +
>  xen/arch/x86/cpuid.c        | 23 +++++++++++++++++++++++
>  xen/arch/x86/setup.c        |  3 +++
>  xen/include/asm-x86/cpuid.h | 22 ++++++++++++++++++++++
>  4 files changed, 49 insertions(+)
>  create mode 100644 xen/arch/x86/cpuid.c

You already introduced xen/arch/x86/cpuid/ in patch 3 - why don't
you put this file there, as e.g. guest.c?

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 07/31] xen/x86: Export host featureset via SYSCTL
  2015-12-16 21:24 ` [PATCH RFC 07/31] xen/x86: Export host featureset via SYSCTL Andrew Cooper
@ 2015-12-22 16:57   ` Jan Beulich
  0 siblings, 0 replies; 123+ messages in thread
From: Jan Beulich @ 2015-12-22 16:57 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Tim Deegan, Ian Campbell, Xen-devel

>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
> @@ -190,6 +191,56 @@ long arch_do_sysctl(
>          }
>          break;
>  
> +    case XEN_SYSCTL_get_featureset:
> +    {
> +        uint32_t *featureset;

const

> +        unsigned int nr;
> +
> +        /* Request for maximum number of features? */
> +        if ( guest_handle_is_null(sysctl->u.featureset.features) )
> +        {
> +            sysctl->u.featureset.nr_features = XEN_NR_FEATURESET_ENTRIES;
> +            if ( __copy_to_guest(u_sysctl, sysctl, 1) )

__copy_field_to_guest()?

> +                ret = -EFAULT;
> +            break;
> +        }
> +
> +        /* Clip the number of entries. */
> +        nr = min_t(unsigned int, sysctl->u.featureset.nr_features,
> +                   XEN_NR_FEATURESET_ENTRIES);

Let's try to avoid min_t() wherever possible.

> --- a/xen/include/public/sysctl.h
> +++ b/xen/include/public/sysctl.h
> @@ -764,6 +764,24 @@ struct xen_sysctl_tmem_op {
>  typedef struct xen_sysctl_tmem_op xen_sysctl_tmem_op_t;
>  DEFINE_XEN_GUEST_HANDLE(xen_sysctl_tmem_op_t);
>  
> +/*
> + * XEN_SYSCTL_get_featureset (x86 specific)

Depending on your further intention this and/or ...

> + *
> + * Return information about the maximum sets of features which can be offered
> + * to different types of guests.  This is all strictly information as found in
> + * `cpuid` feature leaves with no synthetic alterations.
> + */
> +struct xen_sysctl_featureset {
> +#define XEN_SYSCTL_featureset_host      0

... this need to carry "CPU" in their names.

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 01/31] xen/public: Export featureset information in the public API
  2015-12-22 16:42     ` Andrew Cooper
@ 2015-12-22 16:59       ` Jan Beulich
  2015-12-23 10:05         ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Jan Beulich @ 2015-12-22 16:59 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Tim Deegan, Ian Campbell, Xen-devel

>>> On 22.12.15 at 17:42, <andrew.cooper3@citrix.com> wrote:
> On 22/12/15 16:28, Jan Beulich wrote:
>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>> +/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, FSMAX+2 */
>>> +#define X86_FEATURE_XSTORE	((FSMAX+1)*32+ 2) /* on-CPU RNG present (xstore insn) */
>>> +#define X86_FEATURE_XSTORE_EN	((FSMAX+1)*32+ 3) /* on-CPU RNG enabled */
>>> +#define X86_FEATURE_XCRYPT	((FSMAX+1)*32+ 6) /* on-CPU crypto (xcrypt insn) */
>>> +#define X86_FEATURE_XCRYPT_EN	((FSMAX+1)*32+ 7) /* on-CPU crypto enabled */
>>> +#define X86_FEATURE_ACE2	((FSMAX+1)*32+ 8) /* Advanced Cryptography Engine v2 */
>>> +#define X86_FEATURE_ACE2_EN	((FSMAX+1)*32+ 9) /* ACE v2 enabled */
>>> +#define X86_FEATURE_PHE		((FSMAX+1)*32+10) /* PadLock Hash Engine */
>>> +#define X86_FEATURE_PHE_EN	((FSMAX+1)*32+11) /* PHE enabled */
>>> +#define X86_FEATURE_PMM		((FSMAX+1)*32+12) /* PadLock Montgomery Multiplier */
>>> +#define X86_FEATURE_PMM_EN	((FSMAX+1)*32+13) /* PMM enabled */
>> None of these get consumed anywhere - if you already touch this
>> code, just drop all of them.
> 
> X86_FEATURE_XSTORE gets used in xen/arch/x86/cpu/centaur.c to stash word
> 0xC0000001, but nothing actually reads the stashed values.
> 
> I could do a precursor patch which drops the stashing of this
> information, which will result in NCAPINTS getting shorter by the end of
> the series.

Yes, that's what I meant to imply.

>>> +/*
>>> + * CPUID leaf shorthand:
>>> + * - optional 'e', Extended (0x8xxxxxxx)
>>> + * - leaf, uppercase hex
>>> + * - register, lowercase
>>> + * - optional subleaf, uppercase hex
>>> + */
>>> +#define XEN_FEATURESET_1d     0 /* 0x00000001.edx      */
>>> +#define XEN_FEATURESET_1c     1 /* 0x00000001.ecx      */
>>> +#define XEN_FEATURESET_e1d    2 /* 0x80000001.edx      */
>>> +#define XEN_FEATURESET_e1c    3 /* 0x80000001.ecx      */
>>> +#define XEN_FEATURESET_Da1    4 /* 0x0000000d:1.eax    */
>>> +#define XEN_FEATURESET_7b0    5 /* 0x00000007:0.ebx    */
>> This ends up being pretty cryptic.
> 
> Perhaps at a first glance, but there are so many uses that a shorthand
> really is needed.  See especially the MSR masking patches towards the
> end of the series.

I understand that something short is needed. But as the main
identifier in the ABI?

>>> +#define XEN_NR_FEATURESET_ENTRIES (XEN_FEATURESET_7b0 + 1)
>> This shouldn't be exposed, as it will necessarily change sooner or later.
> 
> Hmm yes - I think I can alter where this lives, although libxc does need
> to be able to get this value.

Perhaps keep it where it is, but put it inside #ifdef __XEN__?

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 04/31] xen/x86: Mask out unknown features from Xen's capabilities
  2015-12-22 16:42   ` Jan Beulich
@ 2015-12-22 17:01     ` Andrew Cooper
  0 siblings, 0 replies; 123+ messages in thread
From: Andrew Cooper @ 2015-12-22 17:01 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 22/12/15 16:42, Jan Beulich wrote:
>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>> --- a/xen/arch/x86/cpu/common.c
>> +++ b/xen/arch/x86/cpu/common.c
>> @@ -324,6 +324,7 @@ void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
>>  	 * we do "generic changes."
>>  	 */
>>  	for (i = 0; i < XEN_NR_FEATURESET_ENTRIES; ++i) {
>> +		c->x86_capability[i] &= known_features[i];
>>  		c->x86_capability[i] ^= inverted_features[i];
>>  	}
> Assert that no unknown features slipped into the inverted ones?

For v2, I will have a small program which makes these assertions, and
interrupts the build if they fail.

Most of the required assertions are on automatically generated values,
or automatically derived values.

> But see also below.
>
>> --- a/xen/arch/x86/cpuid/cpuid-private.h
>> +++ b/xen/arch/x86/cpuid/cpuid-private.h
>> @@ -10,6 +10,32 @@
>>  
>>  #endif
>>  
>> +/* Mask of bits which are shared between 1d and e1d. */
>> +#define SHARED_1d                               \
>> +    (cpufeat_mask(X86_FEATURE_FPU)   |          \
>> +     cpufeat_mask(X86_FEATURE_VME)   |          \
>> +     cpufeat_mask(X86_FEATURE_DE)    |          \
>> +     cpufeat_mask(X86_FEATURE_PSE)   |          \
>> +     cpufeat_mask(X86_FEATURE_TSC)   |          \
>> +     cpufeat_mask(X86_FEATURE_MSR)   |          \
>> +     cpufeat_mask(X86_FEATURE_PAE)   |          \
>> +     cpufeat_mask(X86_FEATURE_MCE)   |          \
>> +     cpufeat_mask(X86_FEATURE_CX8)   |          \
>> +     cpufeat_mask(X86_FEATURE_APIC)  |          \
>> +     cpufeat_mask(X86_FEATURE_MTRR)  |          \
>> +     cpufeat_mask(X86_FEATURE_PGE)   |          \
>> +     cpufeat_mask(X86_FEATURE_MCA)   |          \
>> +     cpufeat_mask(X86_FEATURE_CMOV)  |          \
>> +     cpufeat_mask(X86_FEATURE_PAT)   |          \
>> +     cpufeat_mask(X86_FEATURE_PSE36) |          \
>> +     cpufeat_mask(X86_FEATURE_MMX)   |          \
>> +     cpufeat_mask(X86_FEATURE_FXSR))
> These are shared for AMD, but zero in the extended leaf for Intel.

Indeed.  They make handling of feature dependences rather tricky.

>
>> --- a/xen/arch/x86/cpuid/cpuid.c
>> +++ b/xen/arch/x86/cpuid/cpuid.c
>> @@ -1,5 +1,110 @@
>>  #include "cpuid-private.h"
>>  
>> +const uint32_t known_features[XEN_NR_FEATURESET_ENTRIES] =
>> +{
>> +    [cpufeat_word(X86_FEATURE_FPU)] = (SHARED_1d                           |
>> +                                       cpufeat_mask(X86_FEATURE_SEP)       |
> I can see how you try to remove fixed relationship, but using
> FPU in the array index when no FPU appear in the list is at
> least confusing.
>
> Looking at the rest, adding a new feature will become quite a bit
> more involved. I think we need some better abstraction here, e.g.
> a mechanism similar to the one I used in public/errno.h or the one
> Linux uses to populate its syscall tables or /proc/cpuinfo's feature
> list to allow multiple inclusion of a single list of definitions where all
> properties of each individual feature are maintained on one line.
>
> The tables in this file would then be derived from this (perhaps
> via further steps of machine processing).

Actually, patch  16 "x86: Automatically generate known_features" moves
this into the python script which flattens dependencies.

That patch also has a TODO to reorder the series, which would drop most
of this patch.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 03/31] xen/x86: Store antifeatures inverted in a featureset
  2015-12-22 16:32   ` Jan Beulich
@ 2015-12-22 17:03     ` Andrew Cooper
  2016-01-05 14:19       ` Ian Campbell
  0 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-22 17:03 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 22/12/15 16:32, Jan Beulich wrote:
>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>> --- /dev/null
>> +++ b/xen/arch/x86/cpuid/cpuid-private.h
>> @@ -0,0 +1,27 @@
>> +#ifdef __XEN__
>> +
>> +#include <asm/cpufeature.h>
>> +
>> +#include <xen/lib.h>
>> +
>> +#else
>> +
>> +# error TODO for userspace
> I suppose your intentions with this will become apparent in later
> patches?

Everything in xen/arch/x86/cpuid/ is shared code between Xen and libxc,
to avoid having different algorithms/structures between the hypervisor
and toolstack.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 09/31] xen/x86: Calculate PV featureset
  2015-12-16 21:24 ` [PATCH RFC 09/31] xen/x86: Calculate PV featureset Andrew Cooper
@ 2015-12-22 17:07   ` Jan Beulich
  2015-12-22 17:13     ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Jan Beulich @ 2015-12-22 17:07 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Tim Deegan, Ian Campbell, Xen-devel

>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
> --- a/xen/arch/x86/cpuid/cpuid.c
> +++ b/xen/arch/x86/cpuid/cpuid.c
> @@ -102,7 +102,11 @@ const uint32_t known_features[XEN_NR_FEATURESET_ENTRIES] =
>                                              cpufeat_mask(X86_FEATURE_CAT)        |
>                                              cpufeat_mask(X86_FEATURE_RDSEED)     |
>                                              cpufeat_mask(X86_FEATURE_ADX)        |
> -                                            cpufeat_mask(X86_FEATURE_SMAP)),
> +                                            cpufeat_mask(X86_FEATURE_SMAP)       |
> +                                            cpufeat_mask(X86_FEATURE_PCOMMIT)    |
> +                                            cpufeat_mask(X86_FEATURE_CLFLUSHOPT) |
> +                                            cpufeat_mask(X86_FEATURE_CLWB)       |
> +                                            cpufeat_mask(X86_FEATURE_SHA)),
>  
>      [cpufeat_word(X86_FEATURE_PREFETCHWT1)] = (cpufeat_mask(X86_FEATURE_PREFETCHWT1)),
>  
> @@ -116,6 +120,101 @@ const uint32_t inverted_features[XEN_NR_FEATURESET_ENTRIES] =
>      [cpufeat_word(X86_FEATURE_FPU_SEL)] = cpufeat_mask(X86_FEATURE_FPU_SEL),
>  };
>  
> +#define PV_FEATUREMASK_1d                       \
> +    (cpufeat_mask(X86_FEATURE_FPU)    |         \
> +     cpufeat_mask(X86_FEATURE_DE)     |         \
> +     cpufeat_mask(X86_FEATURE_TSC)    |         \
> +     cpufeat_mask(X86_FEATURE_MSR)    |         \
> +     cpufeat_mask(X86_FEATURE_PAE)    |         \
> +     cpufeat_mask(X86_FEATURE_MCE)    |         \
> +     cpufeat_mask(X86_FEATURE_CX8)    |         \
> +     cpufeat_mask(X86_FEATURE_APIC)   |         \
> +     cpufeat_mask(X86_FEATURE_SEP)    |         \
> +     cpufeat_mask(X86_FEATURE_MCA)    |         \
> +     cpufeat_mask(X86_FEATURE_CMOV)   |         \
> +     cpufeat_mask(X86_FEATURE_PAT)    |         \
> +     cpufeat_mask(X86_FEATURE_CLFLSH) |         \
> +     cpufeat_mask(X86_FEATURE_ACPI)   |         \
> +     cpufeat_mask(X86_FEATURE_MMX)    |         \
> +     cpufeat_mask(X86_FEATURE_FXSR)   |         \
> +     cpufeat_mask(X86_FEATURE_XMM)    |         \
> +     cpufeat_mask(X86_FEATURE_XMM2))
> +
> +#define PV_FEATUREMASK_1c                       \
> +    (cpufeat_mask(X86_FEATURE_XMM3)      |      \
> +     cpufeat_mask(X86_FEATURE_PCLMULQDQ) |      \
> +     cpufeat_mask(X86_FEATURE_SSSE3)     |      \
> +     cpufeat_mask(X86_FEATURE_FMA)       |      \
> +     cpufeat_mask(X86_FEATURE_CX16)      |      \
> +     cpufeat_mask(X86_FEATURE_SSE4_1)    |      \
> +     cpufeat_mask(X86_FEATURE_SSE4_2)    |      \
> +     cpufeat_mask(X86_FEATURE_X2APIC)    |      \
> +     cpufeat_mask(X86_FEATURE_MOVBE)     |      \
> +     cpufeat_mask(X86_FEATURE_POPCNT)    |      \
> +     cpufeat_mask(X86_FEATURE_AES)       |      \
> +     cpufeat_mask(X86_FEATURE_XSAVE)     |      \
> +     cpufeat_mask(X86_FEATURE_AVX)       |      \
> +     cpufeat_mask(X86_FEATURE_F16C)      |      \
> +     cpufeat_mask(X86_FEATURE_RDRAND)    |      \
> +     cpufeat_mask(X86_FEATURE_HYPERVISOR))
> +
> +#define PV_FEATUREMASK_e1d                      \
> +    ((PV_FEATUREMASK_1d & SHARED_1d)    |       \
> +     cpufeat_mask(X86_FEATURE_SYSCALL)  |       \
> +     cpufeat_mask(X86_FEATURE_MP)       |       \
> +     cpufeat_mask(X86_FEATURE_NX)       |       \
> +     cpufeat_mask(X86_FEATURE_MMXEXT)   |       \
> +     cpufeat_mask(X86_FEATURE_FFXSR)    |       \
> +     cpufeat_mask(X86_FEATURE_LM)       |       \
> +     cpufeat_mask(X86_FEATURE_3DNOWEXT) |       \
> +     cpufeat_mask(X86_FEATURE_3DNOW))
> +
> +#define PV_FEATUREMASK_e1c                      \
> +    (cpufeat_mask(X86_FEATURE_LAHF_LM)       |  \
> +     cpufeat_mask(X86_FEATURE_ABM)           |  \
> +     cpufeat_mask(X86_FEATURE_SSE4A)         |  \
> +     cpufeat_mask(X86_FEATURE_MISALIGNSSE)   |  \
> +     cpufeat_mask(X86_FEATURE_3DNOWPREFETCH) |  \
> +     cpufeat_mask(X86_FEATURE_XOP)           |  \
> +     cpufeat_mask(X86_FEATURE_LWP)           |  \
> +     cpufeat_mask(X86_FEATURE_FMA4)          |  \
> +     cpufeat_mask(X86_FEATURE_TBM)           |  \
> +     cpufeat_mask(X86_FEATURE_DBEXT))
> +
> +#define PV_FEATUREMASK_Da1                      \
> +    (cpufeat_mask(X86_FEATURE_XSAVEOPT) |       \
> +     cpufeat_mask(X86_FEATURE_XSAVEC)   |       \
> +     cpufeat_mask(X86_FEATURE_XGETBV1))
> +
> +#define PV_FEATUREMASK_7b0                      \
> +    (cpufeat_mask(X86_FEATURE_FSGSBASE)   |     \
> +     cpufeat_mask(X86_FEATURE_BMI1)       |     \
> +     cpufeat_mask(X86_FEATURE_HLE)        |     \
> +     cpufeat_mask(X86_FEATURE_AVX2)       |     \
> +     cpufeat_mask(X86_FEATURE_BMI2)       |     \
> +     cpufeat_mask(X86_FEATURE_ERMS)       |     \
> +     cpufeat_mask(X86_FEATURE_RTM)        |     \
> +     cpufeat_mask(X86_FEATURE_RDSEED)     |     \
> +     cpufeat_mask(X86_FEATURE_ADX)        |     \
> +     cpufeat_mask(X86_FEATURE_PCOMMIT)    |     \
> +     cpufeat_mask(X86_FEATURE_CLFLUSHOPT) |     \
> +     cpufeat_mask(X86_FEATURE_CLWB)       |     \
> +     cpufeat_mask(X86_FEATURE_SHA))
> +
> +#define PV_FEATUREMASK_7c0                      \
> +    (cpufeat_mask(X86_FEATURE_PREFETCHWT1))
> +
> +const uint32_t pv_featuremask[XEN_NR_FEATURESET_ENTRIES] =
> +{
> +    PV_FEATUREMASK_1d,
> +    PV_FEATUREMASK_1c,
> +    PV_FEATUREMASK_e1d,
> +    PV_FEATUREMASK_e1c,
> +    PV_FEATUREMASK_Da1,
> +    PV_FEATUREMASK_7b0,
> +    PV_FEATUREMASK_7c0,
> +};

Why single time used #defines rather than directly populating the
array, just like done above for known_features[]?

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 10/31] xen/x86: Calculate HVM featureset
  2015-12-16 21:24 ` [PATCH RFC 10/31] xen/x86: Calculate HVM featureset Andrew Cooper
@ 2015-12-22 17:11   ` Jan Beulich
  2015-12-22 17:21     ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Jan Beulich @ 2015-12-22 17:11 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Tim Deegan, Ian Campbell, Xen-devel

>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
> @@ -22,6 +24,27 @@ void __init calculate_featuresets(void)
>  
>      /* Unconditionally claim to be able to set the hypervisor bit. */
>      __set_bit(X86_FEATURE_HYPERVISOR, pv_featureset);
> +
> +    /* HVM featureset. */
> +    if ( hvm_enabled )
> +    {
> +        const uint32_t *hvm_featuremask = hvm_funcs.hap_supported
> +            ? hvm_hap_featuremask : hvm_shadow_featuremask;
> +
> +        for ( i = 0; i < ARRAY_SIZE(hvm_featureset); ++i )
> +            hvm_featureset[i] = host_featureset[i] & hvm_featuremask[i];
> +
> +        /* Unconditionally claim to be able to set the hypervisor bit. */
> +        __set_bit(X86_FEATURE_HYPERVISOR, hvm_featureset);
> +
> +        /*
> +         * On AMD, PV guests are entirely unable to use 'sysenter' as Xen runs
> +         * in long mode, but HVM guests are able if running in protected mode.
> +         */
> +        if ( (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) &&
> +             !test_bit(X86_FEATURE_SEP, boot_cpu_data.x86_capability) )

Is the ! correct here? And please use cpu_has_sep.

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 09/31] xen/x86: Calculate PV featureset
  2015-12-22 17:07   ` Jan Beulich
@ 2015-12-22 17:13     ` Andrew Cooper
  2015-12-22 17:18       ` Jan Beulich
  0 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-22 17:13 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Tim Deegan, Ian Campbell, Xen-devel

On 22/12/15 17:07, Jan Beulich wrote:
>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>> --- a/xen/arch/x86/cpuid/cpuid.c
>> +++ b/xen/arch/x86/cpuid/cpuid.c
>> @@ -102,7 +102,11 @@ const uint32_t known_features[XEN_NR_FEATURESET_ENTRIES] =
>>                                              cpufeat_mask(X86_FEATURE_CAT)        |
>>                                              cpufeat_mask(X86_FEATURE_RDSEED)     |
>>                                              cpufeat_mask(X86_FEATURE_ADX)        |
>> -                                            cpufeat_mask(X86_FEATURE_SMAP)),
>> +                                            cpufeat_mask(X86_FEATURE_SMAP)       |
>> +                                            cpufeat_mask(X86_FEATURE_PCOMMIT)    |
>> +                                            cpufeat_mask(X86_FEATURE_CLFLUSHOPT) |
>> +                                            cpufeat_mask(X86_FEATURE_CLWB)       |
>> +                                            cpufeat_mask(X86_FEATURE_SHA)),
>>  
>>      [cpufeat_word(X86_FEATURE_PREFETCHWT1)] = (cpufeat_mask(X86_FEATURE_PREFETCHWT1)),
>>  
>> @@ -116,6 +120,101 @@ const uint32_t inverted_features[XEN_NR_FEATURESET_ENTRIES] =
>>      [cpufeat_word(X86_FEATURE_FPU_SEL)] = cpufeat_mask(X86_FEATURE_FPU_SEL),
>>  };
>>  
>> +#define PV_FEATUREMASK_1d                       \
>> +    (cpufeat_mask(X86_FEATURE_FPU)    |         \
>> +     cpufeat_mask(X86_FEATURE_DE)     |         \
>> +     cpufeat_mask(X86_FEATURE_TSC)    |         \
>> +     cpufeat_mask(X86_FEATURE_MSR)    |         \
>> +     cpufeat_mask(X86_FEATURE_PAE)    |         \
>> +     cpufeat_mask(X86_FEATURE_MCE)    |         \
>> +     cpufeat_mask(X86_FEATURE_CX8)    |         \
>> +     cpufeat_mask(X86_FEATURE_APIC)   |         \
>> +     cpufeat_mask(X86_FEATURE_SEP)    |         \
>> +     cpufeat_mask(X86_FEATURE_MCA)    |         \
>> +     cpufeat_mask(X86_FEATURE_CMOV)   |         \
>> +     cpufeat_mask(X86_FEATURE_PAT)    |         \
>> +     cpufeat_mask(X86_FEATURE_CLFLSH) |         \
>> +     cpufeat_mask(X86_FEATURE_ACPI)   |         \
>> +     cpufeat_mask(X86_FEATURE_MMX)    |         \
>> +     cpufeat_mask(X86_FEATURE_FXSR)   |         \
>> +     cpufeat_mask(X86_FEATURE_XMM)    |         \
>> +     cpufeat_mask(X86_FEATURE_XMM2))
>> +
>> +#define PV_FEATUREMASK_1c                       \
>> +    (cpufeat_mask(X86_FEATURE_XMM3)      |      \
>> +     cpufeat_mask(X86_FEATURE_PCLMULQDQ) |      \
>> +     cpufeat_mask(X86_FEATURE_SSSE3)     |      \
>> +     cpufeat_mask(X86_FEATURE_FMA)       |      \
>> +     cpufeat_mask(X86_FEATURE_CX16)      |      \
>> +     cpufeat_mask(X86_FEATURE_SSE4_1)    |      \
>> +     cpufeat_mask(X86_FEATURE_SSE4_2)    |      \
>> +     cpufeat_mask(X86_FEATURE_X2APIC)    |      \
>> +     cpufeat_mask(X86_FEATURE_MOVBE)     |      \
>> +     cpufeat_mask(X86_FEATURE_POPCNT)    |      \
>> +     cpufeat_mask(X86_FEATURE_AES)       |      \
>> +     cpufeat_mask(X86_FEATURE_XSAVE)     |      \
>> +     cpufeat_mask(X86_FEATURE_AVX)       |      \
>> +     cpufeat_mask(X86_FEATURE_F16C)      |      \
>> +     cpufeat_mask(X86_FEATURE_RDRAND)    |      \
>> +     cpufeat_mask(X86_FEATURE_HYPERVISOR))
>> +
>> +#define PV_FEATUREMASK_e1d                      \
>> +    ((PV_FEATUREMASK_1d & SHARED_1d)    |       \
>> +     cpufeat_mask(X86_FEATURE_SYSCALL)  |       \
>> +     cpufeat_mask(X86_FEATURE_MP)       |       \
>> +     cpufeat_mask(X86_FEATURE_NX)       |       \
>> +     cpufeat_mask(X86_FEATURE_MMXEXT)   |       \
>> +     cpufeat_mask(X86_FEATURE_FFXSR)    |       \
>> +     cpufeat_mask(X86_FEATURE_LM)       |       \
>> +     cpufeat_mask(X86_FEATURE_3DNOWEXT) |       \
>> +     cpufeat_mask(X86_FEATURE_3DNOW))
>> +
>> +#define PV_FEATUREMASK_e1c                      \
>> +    (cpufeat_mask(X86_FEATURE_LAHF_LM)       |  \
>> +     cpufeat_mask(X86_FEATURE_ABM)           |  \
>> +     cpufeat_mask(X86_FEATURE_SSE4A)         |  \
>> +     cpufeat_mask(X86_FEATURE_MISALIGNSSE)   |  \
>> +     cpufeat_mask(X86_FEATURE_3DNOWPREFETCH) |  \
>> +     cpufeat_mask(X86_FEATURE_XOP)           |  \
>> +     cpufeat_mask(X86_FEATURE_LWP)           |  \
>> +     cpufeat_mask(X86_FEATURE_FMA4)          |  \
>> +     cpufeat_mask(X86_FEATURE_TBM)           |  \
>> +     cpufeat_mask(X86_FEATURE_DBEXT))
>> +
>> +#define PV_FEATUREMASK_Da1                      \
>> +    (cpufeat_mask(X86_FEATURE_XSAVEOPT) |       \
>> +     cpufeat_mask(X86_FEATURE_XSAVEC)   |       \
>> +     cpufeat_mask(X86_FEATURE_XGETBV1))
>> +
>> +#define PV_FEATUREMASK_7b0                      \
>> +    (cpufeat_mask(X86_FEATURE_FSGSBASE)   |     \
>> +     cpufeat_mask(X86_FEATURE_BMI1)       |     \
>> +     cpufeat_mask(X86_FEATURE_HLE)        |     \
>> +     cpufeat_mask(X86_FEATURE_AVX2)       |     \
>> +     cpufeat_mask(X86_FEATURE_BMI2)       |     \
>> +     cpufeat_mask(X86_FEATURE_ERMS)       |     \
>> +     cpufeat_mask(X86_FEATURE_RTM)        |     \
>> +     cpufeat_mask(X86_FEATURE_RDSEED)     |     \
>> +     cpufeat_mask(X86_FEATURE_ADX)        |     \
>> +     cpufeat_mask(X86_FEATURE_PCOMMIT)    |     \
>> +     cpufeat_mask(X86_FEATURE_CLFLUSHOPT) |     \
>> +     cpufeat_mask(X86_FEATURE_CLWB)       |     \
>> +     cpufeat_mask(X86_FEATURE_SHA))
>> +
>> +#define PV_FEATUREMASK_7c0                      \
>> +    (cpufeat_mask(X86_FEATURE_PREFETCHWT1))
>> +
>> +const uint32_t pv_featuremask[XEN_NR_FEATURESET_ENTRIES] =
>> +{
>> +    PV_FEATUREMASK_1d,
>> +    PV_FEATUREMASK_1c,
>> +    PV_FEATUREMASK_e1d,
>> +    PV_FEATUREMASK_e1c,
>> +    PV_FEATUREMASK_Da1,
>> +    PV_FEATUREMASK_7b0,
>> +    PV_FEATUREMASK_7c0,
>> +};
> Why single time used #defines rather than directly populating the
> array, just like done above for known_features[]?

That will become clear with the following patch, where HVM becomes
strictly an extension of PV.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 11/31] xen/x86: Calculate Raw featureset
  2015-12-16 21:24 ` [PATCH RFC 11/31] xen/x86: Calculate Raw featureset Andrew Cooper
@ 2015-12-22 17:14   ` Jan Beulich
  2015-12-22 17:27     ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Jan Beulich @ 2015-12-22 17:14 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Tim Deegan, Ian Campbell, Xen-devel

>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
> Calculate and expose the raw featureset to userspace.  This is for
> informational purposes; the difference between the raw and the host
> featuresets are the features Xen has specifically chosen not to use.

And what use is this? Looks like dead code to me...

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 05/31] xen/x86: Collect more CPUID feature words
  2015-12-22 16:46   ` Jan Beulich
@ 2015-12-22 17:17     ` Andrew Cooper
  0 siblings, 0 replies; 123+ messages in thread
From: Andrew Cooper @ 2015-12-22 17:17 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 22/12/15 16:46, Jan Beulich wrote:
>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>> --- a/xen/arch/x86/cpu/amd.c
>> +++ b/xen/arch/x86/cpu/amd.c
>> @@ -481,7 +481,7 @@ static void __devinit init_amd(struct cpuinfo_x86 *c)
>>  
>>  	if (c->extended_cpuid_level >= 0x80000007) {
>>  		c->x86_power = cpuid_edx(0x80000007);
>> -		if (c->x86_power & (1<<8)) {
>> +		if (c->x86_power & cpufeat_mask(X86_FEATURE_ITSC)) {
> generic_identify() has already run by the time we get here, so no
> need to re-read cpuid_edx() (interestingly enough you leverage
> this in init_intel()).

I didn't change either in this regard (observe that it is just in
context), although it is now obvious that x86_power can be dropped
completely, given that isn't used anywhere else.

andrewcoop@andrewcoop:/local/xen.git/xen$ git grep x86_power
arch/x86/cpu/amd.c:541:         c->x86_power = cpuid_edx(0x80000007);
arch/x86/cpu/amd.c:542:         if (c->x86_power &
cpufeat_mask(X86_FEATURE_ITSC)) {
include/asm-x86/processor.h:194:    int  x86_power;


>
>> --- a/xen/arch/x86/cpuid/cpuid.c
>> +++ b/xen/arch/x86/cpuid/cpuid.c
>> @@ -103,6 +103,12 @@ const uint32_t known_features[XEN_NR_FEATURESET_ENTRIES] =
>>                                              cpufeat_mask(X86_FEATURE_RDSEED)     |
>>                                              cpufeat_mask(X86_FEATURE_ADX)        |
>>                                              cpufeat_mask(X86_FEATURE_SMAP)),
>> +
>> +    [cpufeat_word(X86_FEATURE_PREFETCHWT1)] = (cpufeat_mask(X86_FEATURE_PREFETCHWT1)),
>> +
>> +    [cpufeat_word(X86_FEATURE_ITSC)] = (cpufeat_mask(X86_FEATURE_ITSC)),
>> +
>> +    [cpufeat_word(X86_FEATURE_CLZERO)] = (cpufeat_mask(X86_FEATURE_CLZERO)),
>>  };
> Are these indeed the only ones in their groups that can be safely
> marked "known"?

I am going to go out on a limb and say yes here.  The point of "known"
is "someone has actively thought about what the hyperivsor implications
of using this feature is".  These are the only ones which I feel safe
declaring to be such at the time of writing.

Rebasing onto staging has introduced the PKU bits, which are adjacent to
PREFETCHWT1, and altered this patch quite a lot.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 09/31] xen/x86: Calculate PV featureset
  2015-12-22 17:13     ` Andrew Cooper
@ 2015-12-22 17:18       ` Jan Beulich
  0 siblings, 0 replies; 123+ messages in thread
From: Jan Beulich @ 2015-12-22 17:18 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Tim Deegan, Ian Campbell, Xen-devel

>>> On 22.12.15 at 18:13, <andrew.cooper3@citrix.com> wrote:
> On 22/12/15 17:07, Jan Beulich wrote:
>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>> --- a/xen/arch/x86/cpuid/cpuid.c
>>> +++ b/xen/arch/x86/cpuid/cpuid.c
>>> @@ -102,7 +102,11 @@ const uint32_t known_features[XEN_NR_FEATURESET_ENTRIES] 
> =
>>>                                              cpufeat_mask(X86_FEATURE_CAT)   
>      |
>>>                                              
> cpufeat_mask(X86_FEATURE_RDSEED)     |
>>>                                              cpufeat_mask(X86_FEATURE_ADX)   
>      |
>>> -                                            cpufeat_mask(X86_FEATURE_SMAP)),
>>> +                                            cpufeat_mask(X86_FEATURE_SMAP)  
>      |
>>> +                                            
> cpufeat_mask(X86_FEATURE_PCOMMIT)    |
>>> +                                            
> cpufeat_mask(X86_FEATURE_CLFLUSHOPT) |
>>> +                                            cpufeat_mask(X86_FEATURE_CLWB)  
>      |
>>> +                                            cpufeat_mask(X86_FEATURE_SHA)),
>>>  
>>>      [cpufeat_word(X86_FEATURE_PREFETCHWT1)] = 
> (cpufeat_mask(X86_FEATURE_PREFETCHWT1)),
>>>  
>>> @@ -116,6 +120,101 @@ const uint32_t 
> inverted_features[XEN_NR_FEATURESET_ENTRIES] =
>>>      [cpufeat_word(X86_FEATURE_FPU_SEL)] = 
> cpufeat_mask(X86_FEATURE_FPU_SEL),
>>>  };
>>>  
>>> +#define PV_FEATUREMASK_1d                       \
>>> +    (cpufeat_mask(X86_FEATURE_FPU)    |         \
>>> +     cpufeat_mask(X86_FEATURE_DE)     |         \
>>> +     cpufeat_mask(X86_FEATURE_TSC)    |         \
>>> +     cpufeat_mask(X86_FEATURE_MSR)    |         \
>>> +     cpufeat_mask(X86_FEATURE_PAE)    |         \
>>> +     cpufeat_mask(X86_FEATURE_MCE)    |         \
>>> +     cpufeat_mask(X86_FEATURE_CX8)    |         \
>>> +     cpufeat_mask(X86_FEATURE_APIC)   |         \
>>> +     cpufeat_mask(X86_FEATURE_SEP)    |         \
>>> +     cpufeat_mask(X86_FEATURE_MCA)    |         \
>>> +     cpufeat_mask(X86_FEATURE_CMOV)   |         \
>>> +     cpufeat_mask(X86_FEATURE_PAT)    |         \
>>> +     cpufeat_mask(X86_FEATURE_CLFLSH) |         \
>>> +     cpufeat_mask(X86_FEATURE_ACPI)   |         \
>>> +     cpufeat_mask(X86_FEATURE_MMX)    |         \
>>> +     cpufeat_mask(X86_FEATURE_FXSR)   |         \
>>> +     cpufeat_mask(X86_FEATURE_XMM)    |         \
>>> +     cpufeat_mask(X86_FEATURE_XMM2))
>>> +
>>> +#define PV_FEATUREMASK_1c                       \
>>> +    (cpufeat_mask(X86_FEATURE_XMM3)      |      \
>>> +     cpufeat_mask(X86_FEATURE_PCLMULQDQ) |      \
>>> +     cpufeat_mask(X86_FEATURE_SSSE3)     |      \
>>> +     cpufeat_mask(X86_FEATURE_FMA)       |      \
>>> +     cpufeat_mask(X86_FEATURE_CX16)      |      \
>>> +     cpufeat_mask(X86_FEATURE_SSE4_1)    |      \
>>> +     cpufeat_mask(X86_FEATURE_SSE4_2)    |      \
>>> +     cpufeat_mask(X86_FEATURE_X2APIC)    |      \
>>> +     cpufeat_mask(X86_FEATURE_MOVBE)     |      \
>>> +     cpufeat_mask(X86_FEATURE_POPCNT)    |      \
>>> +     cpufeat_mask(X86_FEATURE_AES)       |      \
>>> +     cpufeat_mask(X86_FEATURE_XSAVE)     |      \
>>> +     cpufeat_mask(X86_FEATURE_AVX)       |      \
>>> +     cpufeat_mask(X86_FEATURE_F16C)      |      \
>>> +     cpufeat_mask(X86_FEATURE_RDRAND)    |      \
>>> +     cpufeat_mask(X86_FEATURE_HYPERVISOR))
>>> +
>>> +#define PV_FEATUREMASK_e1d                      \
>>> +    ((PV_FEATUREMASK_1d & SHARED_1d)    |       \
>>> +     cpufeat_mask(X86_FEATURE_SYSCALL)  |       \
>>> +     cpufeat_mask(X86_FEATURE_MP)       |       \
>>> +     cpufeat_mask(X86_FEATURE_NX)       |       \
>>> +     cpufeat_mask(X86_FEATURE_MMXEXT)   |       \
>>> +     cpufeat_mask(X86_FEATURE_FFXSR)    |       \
>>> +     cpufeat_mask(X86_FEATURE_LM)       |       \
>>> +     cpufeat_mask(X86_FEATURE_3DNOWEXT) |       \
>>> +     cpufeat_mask(X86_FEATURE_3DNOW))
>>> +
>>> +#define PV_FEATUREMASK_e1c                      \
>>> +    (cpufeat_mask(X86_FEATURE_LAHF_LM)       |  \
>>> +     cpufeat_mask(X86_FEATURE_ABM)           |  \
>>> +     cpufeat_mask(X86_FEATURE_SSE4A)         |  \
>>> +     cpufeat_mask(X86_FEATURE_MISALIGNSSE)   |  \
>>> +     cpufeat_mask(X86_FEATURE_3DNOWPREFETCH) |  \
>>> +     cpufeat_mask(X86_FEATURE_XOP)           |  \
>>> +     cpufeat_mask(X86_FEATURE_LWP)           |  \
>>> +     cpufeat_mask(X86_FEATURE_FMA4)          |  \
>>> +     cpufeat_mask(X86_FEATURE_TBM)           |  \
>>> +     cpufeat_mask(X86_FEATURE_DBEXT))
>>> +
>>> +#define PV_FEATUREMASK_Da1                      \
>>> +    (cpufeat_mask(X86_FEATURE_XSAVEOPT) |       \
>>> +     cpufeat_mask(X86_FEATURE_XSAVEC)   |       \
>>> +     cpufeat_mask(X86_FEATURE_XGETBV1))
>>> +
>>> +#define PV_FEATUREMASK_7b0                      \
>>> +    (cpufeat_mask(X86_FEATURE_FSGSBASE)   |     \
>>> +     cpufeat_mask(X86_FEATURE_BMI1)       |     \
>>> +     cpufeat_mask(X86_FEATURE_HLE)        |     \
>>> +     cpufeat_mask(X86_FEATURE_AVX2)       |     \
>>> +     cpufeat_mask(X86_FEATURE_BMI2)       |     \
>>> +     cpufeat_mask(X86_FEATURE_ERMS)       |     \
>>> +     cpufeat_mask(X86_FEATURE_RTM)        |     \
>>> +     cpufeat_mask(X86_FEATURE_RDSEED)     |     \
>>> +     cpufeat_mask(X86_FEATURE_ADX)        |     \
>>> +     cpufeat_mask(X86_FEATURE_PCOMMIT)    |     \
>>> +     cpufeat_mask(X86_FEATURE_CLFLUSHOPT) |     \
>>> +     cpufeat_mask(X86_FEATURE_CLWB)       |     \
>>> +     cpufeat_mask(X86_FEATURE_SHA))
>>> +
>>> +#define PV_FEATUREMASK_7c0                      \
>>> +    (cpufeat_mask(X86_FEATURE_PREFETCHWT1))
>>> +
>>> +const uint32_t pv_featuremask[XEN_NR_FEATURESET_ENTRIES] =
>>> +{
>>> +    PV_FEATUREMASK_1d,
>>> +    PV_FEATUREMASK_1c,
>>> +    PV_FEATUREMASK_e1d,
>>> +    PV_FEATUREMASK_e1c,
>>> +    PV_FEATUREMASK_Da1,
>>> +    PV_FEATUREMASK_7b0,
>>> +    PV_FEATUREMASK_7c0,
>>> +};
>> Why single time used #defines rather than directly populating the
>> array, just like done above for known_features[]?
> 
> That will become clear with the following patch, where HVM becomes
> strictly an extension of PV.

I've just seen that. However, much of this would be unnecessary
when things got generated from a single table.

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 10/31] xen/x86: Calculate HVM featureset
  2015-12-22 17:11   ` Jan Beulich
@ 2015-12-22 17:21     ` Andrew Cooper
  0 siblings, 0 replies; 123+ messages in thread
From: Andrew Cooper @ 2015-12-22 17:21 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Tim Deegan, Ian Campbell, Xen-devel

On 22/12/15 17:11, Jan Beulich wrote:
>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>> @@ -22,6 +24,27 @@ void __init calculate_featuresets(void)
>>  
>>      /* Unconditionally claim to be able to set the hypervisor bit. */
>>      __set_bit(X86_FEATURE_HYPERVISOR, pv_featureset);
>> +
>> +    /* HVM featureset. */
>> +    if ( hvm_enabled )
>> +    {
>> +        const uint32_t *hvm_featuremask = hvm_funcs.hap_supported
>> +            ? hvm_hap_featuremask : hvm_shadow_featuremask;
>> +
>> +        for ( i = 0; i < ARRAY_SIZE(hvm_featureset); ++i )
>> +            hvm_featureset[i] = host_featureset[i] & hvm_featuremask[i];
>> +
>> +        /* Unconditionally claim to be able to set the hypervisor bit. */
>> +        __set_bit(X86_FEATURE_HYPERVISOR, hvm_featureset);
>> +
>> +        /*
>> +         * On AMD, PV guests are entirely unable to use 'sysenter' as Xen runs
>> +         * in long mode, but HVM guests are able if running in protected mode.
>> +         */
>> +        if ( (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) &&
>> +             !test_bit(X86_FEATURE_SEP, boot_cpu_data.x86_capability) )
> Is the ! correct here?

Yes - init_amd() deliberately clobbers the feature.

> And please use cpu_has_sep.

Actually, thinking about it, the check isn't quite correct.  We need to
only advertise the feature if it was available before init_amd()
clobbered it.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 11/31] xen/x86: Calculate Raw featureset
  2015-12-22 17:14   ` Jan Beulich
@ 2015-12-22 17:27     ` Andrew Cooper
  0 siblings, 0 replies; 123+ messages in thread
From: Andrew Cooper @ 2015-12-22 17:27 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Tim Deegan, Ian Campbell, Xen-devel

On 22/12/15 17:14, Jan Beulich wrote:
>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>> Calculate and expose the raw featureset to userspace.  This is for
>> informational purposes; the difference between the raw and the host
>> featuresets are the features Xen has specifically chosen not to use.
> And what use is this? Looks like dead code to me...

It is specifically needed by XenServers toolstack to safely import VMs
from older versions.  I expect the same will be true for any other
toolstack which attempted to do multi-host levelling, although libxl
doesn't need it because it doesn't even pretend do to levelling.

It turns out that it is also needed to correct the AMD SEP check in
patch 10.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 01/31] xen/public: Export featureset information in the public API
  2015-12-22 16:59       ` Jan Beulich
@ 2015-12-23 10:05         ` Andrew Cooper
  2015-12-23 10:24           ` Jan Beulich
  0 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-23 10:05 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Tim Deegan, Ian Campbell, Xen-devel

On 22/12/2015 16:59, Jan Beulich wrote:
>>>> On 22.12.15 at 17:42, <andrew.cooper3@citrix.com> wrote:
>> On 22/12/15 16:28, Jan Beulich wrote:
>>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>>> +/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, FSMAX+2 */
>>>> +#define X86_FEATURE_XSTORE	((FSMAX+1)*32+ 2) /* on-CPU RNG present (xstore insn) */
>>>> +#define X86_FEATURE_XSTORE_EN	((FSMAX+1)*32+ 3) /* on-CPU RNG enabled */
>>>> +#define X86_FEATURE_XCRYPT	((FSMAX+1)*32+ 6) /* on-CPU crypto (xcrypt insn) */
>>>> +#define X86_FEATURE_XCRYPT_EN	((FSMAX+1)*32+ 7) /* on-CPU crypto enabled */
>>>> +#define X86_FEATURE_ACE2	((FSMAX+1)*32+ 8) /* Advanced Cryptography Engine v2 */
>>>> +#define X86_FEATURE_ACE2_EN	((FSMAX+1)*32+ 9) /* ACE v2 enabled */
>>>> +#define X86_FEATURE_PHE		((FSMAX+1)*32+10) /* PadLock Hash Engine */
>>>> +#define X86_FEATURE_PHE_EN	((FSMAX+1)*32+11) /* PHE enabled */
>>>> +#define X86_FEATURE_PMM		((FSMAX+1)*32+12) /* PadLock Montgomery Multiplier */
>>>> +#define X86_FEATURE_PMM_EN	((FSMAX+1)*32+13) /* PMM enabled */
>>> None of these get consumed anywhere - if you already touch this
>>> code, just drop all of them.
>> X86_FEATURE_XSTORE gets used in xen/arch/x86/cpu/centaur.c to stash word
>> 0xC0000001, but nothing actually reads the stashed values.
>>
>> I could do a precursor patch which drops the stashing of this
>> information, which will result in NCAPINTS getting shorter by the end of
>> the series.
> Yes, that's what I meant to imply.
>
>>>> +/*
>>>> + * CPUID leaf shorthand:
>>>> + * - optional 'e', Extended (0x8xxxxxxx)
>>>> + * - leaf, uppercase hex
>>>> + * - register, lowercase
>>>> + * - optional subleaf, uppercase hex
>>>> + */
>>>> +#define XEN_FEATURESET_1d     0 /* 0x00000001.edx      */
>>>> +#define XEN_FEATURESET_1c     1 /* 0x00000001.ecx      */
>>>> +#define XEN_FEATURESET_e1d    2 /* 0x80000001.edx      */
>>>> +#define XEN_FEATURESET_e1c    3 /* 0x80000001.ecx      */
>>>> +#define XEN_FEATURESET_Da1    4 /* 0x0000000d:1.eax    */
>>>> +#define XEN_FEATURESET_7b0    5 /* 0x00000007:0.ebx    */
>>> This ends up being pretty cryptic.
>> Perhaps at a first glance, but there are so many uses that a shorthand
>> really is needed.  See especially the MSR masking patches towards the
>> end of the series.
> I understand that something short is needed. But as the main
> identifier in the ABI?

It really comes down to whom is intended to do what with a featureset.

These values are derivable as functions of the feature values
themselves, but that requires an assumption that the featureset bitmap
mirrors hardware precisely.  Providing this (names not withstanding) as
a part of the ABI is intended to provide that assurance.

I fully intend higher levels of the toolstack to deal with a featureset
as an arbitrary bitmap, but lower levels like libxc do need a greater
level of understanding of its layout.

>
>>>> +#define XEN_NR_FEATURESET_ENTRIES (XEN_FEATURESET_7b0 + 1)
>>> This shouldn't be exposed, as it will necessarily change sooner or later.
>> Hmm yes - I think I can alter where this lives, although libxc does need
>> to be able to get this value.
> Perhaps keep it where it is, but put it inside #ifdef __XEN__?

I reckon it would be better in cpuid-private.h, strictly making it
accessible only to to the components sharing that library.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 01/31] xen/public: Export featureset information in the public API
  2015-12-23 10:05         ` Andrew Cooper
@ 2015-12-23 10:24           ` Jan Beulich
  2015-12-23 11:26             ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Jan Beulich @ 2015-12-23 10:24 UTC (permalink / raw)
  To: andrew.cooper3; +Cc: tim, Ian.Campbell, xen-devel

>>> Andrew Cooper <andrew.cooper3@citrix.com> 12/23/15 11:05 AM >>>
>On 22/12/2015 16:59, Jan Beulich wrote:
>>>>> On 22.12.15 at 17:42, <andrew.cooper3@citrix.com> wrote:
>>> On 22/12/15 16:28, Jan Beulich wrote:
>>>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>>>> +#define XEN_FEATURESET_1d     0 /* 0x00000001.edx      */
>>>>> +#define XEN_FEATURESET_1c     1 /* 0x00000001.ecx      */
>>>>> +#define XEN_FEATURESET_e1d    2 /* 0x80000001.edx      */
>>>>> +#define XEN_FEATURESET_e1c    3 /* 0x80000001.ecx      */
>>>>> +#define XEN_FEATURESET_Da1    4 /* 0x0000000d:1.eax    */
>>>>> +#define XEN_FEATURESET_7b0    5 /* 0x00000007:0.ebx    */
>>>> This ends up being pretty cryptic.
>>> Perhaps at a first glance, but there are so many uses that a shorthand
>>> really is needed.  See especially the MSR masking patches towards the
>>> end of the series.
>> I understand that something short is needed. But as the main
>> identifier in the ABI?
>
>It really comes down to whom is intended to do what with a featureset.
>
>These values are derivable as functions of the feature values
>themselves, but that requires an assumption that the featureset bitmap
>mirrors hardware precisely.  Providing this (names not withstanding) as
>a part of the ABI is intended to provide that assurance.
>
>I fully intend higher levels of the toolstack to deal with a featureset
>as an arbitrary bitmap, but lower levels like libxc do need a greater
>level of understanding of its layout.

All understood. The question just is whether the main identifiers in the public
header should be this cryptic, or whether consumers should instead introduce
shortcuts of their liking (even more so that, just like noted elsewhere, these
identifiers also lack "CPU" and perhaps "x86" in their names - in the end
feature leveling isn't something that's needed on x86 only).

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 01/31] xen/public: Export featureset information in the public API
  2015-12-23 10:24           ` Jan Beulich
@ 2015-12-23 11:26             ` Andrew Cooper
  2016-01-06  7:43               ` Jan Beulich
  0 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2015-12-23 11:26 UTC (permalink / raw)
  To: Jan Beulich; +Cc: tim, Ian.Campbell, xen-devel

On 23/12/2015 10:24, Jan Beulich wrote:
>>>> Andrew Cooper <andrew.cooper3@citrix.com> 12/23/15 11:05 AM >>>
>> On 22/12/2015 16:59, Jan Beulich wrote:
>>>>>> On 22.12.15 at 17:42, <andrew.cooper3@citrix.com> wrote:
>>>> On 22/12/15 16:28, Jan Beulich wrote:
>>>>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>>>>> +#define XEN_FEATURESET_1d     0 /* 0x00000001.edx      */
>>>>>> +#define XEN_FEATURESET_1c     1 /* 0x00000001.ecx      */
>>>>>> +#define XEN_FEATURESET_e1d    2 /* 0x80000001.edx      */
>>>>>> +#define XEN_FEATURESET_e1c    3 /* 0x80000001.ecx      */
>>>>>> +#define XEN_FEATURESET_Da1    4 /* 0x0000000d:1.eax    */
>>>>>> +#define XEN_FEATURESET_7b0    5 /* 0x00000007:0.ebx    */
>>>>> This ends up being pretty cryptic.
>>>> Perhaps at a first glance, but there are so many uses that a shorthand
>>>> really is needed.  See especially the MSR masking patches towards the
>>>> end of the series.
>>> I understand that something short is needed. But as the main
>>> identifier in the ABI?
>> It really comes down to whom is intended to do what with a featureset.
>>
>> These values are derivable as functions of the feature values
>> themselves, but that requires an assumption that the featureset bitmap
>> mirrors hardware precisely.  Providing this (names not withstanding) as
>> a part of the ABI is intended to provide that assurance.
>>
>> I fully intend higher levels of the toolstack to deal with a featureset
>> as an arbitrary bitmap, but lower levels like libxc do need a greater
>> level of understanding of its layout.
> All understood. The question just is whether the main identifiers in the public
> header should be this cryptic, or whether consumers should instead introduce
> shortcuts of their liking (even more so that, just like noted elsewhere, these
> identifiers also lack "CPU" and perhaps "x86" in their names - in the end
> feature leveling isn't something that's needed on x86 only).

For now, I can move them along with XEN_NR_FEATURESET_ENTRIES, because
the only bits of libxc which need them are the bits which are already
using the shared library.


The slight conceptual issue I am concerned about is how this will fit in
with extended work to fix the rest of cpuid handling in Xen.

Other quantities, such as max_leaf and max_phys_addr need levelling
across hosts.  At the moment, all of this information is derived from
dom0's view and is not kept consistent across migrate.  (Surprisingly,
windows notices this, doesn't crash, and decides to install a new CPU
driver.)

Long term, the toolstack needs to level a complete idea of the cpuid
policy for the guest, and the featureset is just one part of this. 
However, I am expecting that the featureset on its own will still be a
useful entity, which is why I progressed down this route.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 02/31] tools/libxc: Use public/featureset.h for cpuid policy generation
  2015-12-22 16:29   ` Jan Beulich
@ 2016-01-05 14:13     ` Ian Campbell
  2016-01-05 14:17       ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Ian Campbell @ 2016-01-05 14:13 UTC (permalink / raw)
  To: Jan Beulich, Andrew Cooper; +Cc: Ian Jackson, Tim Deegan, Xen-devel

On Tue, 2015-12-22 at 09:29 -0700, Jan Beulich wrote:
> > > > On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
> > --- a/xen/include/public/arch-x86/featureset.h
> > +++ b/xen/include/public/arch-x86/featureset.h
> > @@ -163,6 +163,7 @@
> >  
> >  /* Intel-defined CPU features, CPUID level 0x00000007:0.ebx, word 5 */
> >  #define X86_FEATURE_FSGSBASE      ( 5*32+ 0) /* {RD,WR}{FS,GS}BASE
> > instructions */
> > +#define X86_FEATURE_TSC_ADJUST    ( 5*32+ 1) /* TSC_ADJUST MSR
> > available */
> 
> This would probably better go into patch 1.

Tools would then see this defined twice with only patch 1 applied, and
since the value is actually different I think the compiler will complain.

-#define X86_FEATURE_TSC_ADJUST   1 /* Tsc thread offset */
+#define X86_FEATURE_TSC_ADJUST    ( 5*32+ 1) /* TSC_ADJUST MSR available */

The comment change seems to be a semantic one? Or was it wrong beofre?

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 02/31] tools/libxc: Use public/featureset.h for cpuid policy generation
  2016-01-05 14:13     ` Ian Campbell
@ 2016-01-05 14:17       ` Andrew Cooper
  2016-01-05 14:18         ` Ian Campbell
  0 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2016-01-05 14:17 UTC (permalink / raw)
  To: Ian Campbell, Jan Beulich; +Cc: Ian Jackson, Tim Deegan, Xen-devel

On 05/01/16 14:13, Ian Campbell wrote:
> On Tue, 2015-12-22 at 09:29 -0700, Jan Beulich wrote:
>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>> --- a/xen/include/public/arch-x86/featureset.h
>>> +++ b/xen/include/public/arch-x86/featureset.h
>>> @@ -163,6 +163,7 @@
>>>  
>>>  /* Intel-defined CPU features, CPUID level 0x00000007:0.ebx, word 5 */
>>>  #define X86_FEATURE_FSGSBASE      ( 5*32+ 0) /* {RD,WR}{FS,GS}BASE
>>> instructions */
>>> +#define X86_FEATURE_TSC_ADJUST    ( 5*32+ 1) /* TSC_ADJUST MSR
>>> available */
>> This would probably better go into patch 1.
> Tools would then see this defined twice with only patch 1 applied, and
> since the value is actually different I think the compiler will complain.
>
> -#define X86_FEATURE_TSC_ADJUST   1 /* Tsc thread offset */
> +#define X86_FEATURE_TSC_ADJUST    ( 5*32+ 1) /* TSC_ADJUST MSR available */
>
> The comment change seems to be a semantic one? Or was it wrong beofre?

Changing patch 1 won't affect the compilation of libxc.  Observe in the
penultimate hunk that I also change the #include

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 02/31] tools/libxc: Use public/featureset.h for cpuid policy generation
  2016-01-05 14:17       ` Andrew Cooper
@ 2016-01-05 14:18         ` Ian Campbell
  2016-01-05 14:23           ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Ian Campbell @ 2016-01-05 14:18 UTC (permalink / raw)
  To: Andrew Cooper, Jan Beulich; +Cc: Ian Jackson, Tim Deegan, Xen-devel

On Tue, 2016-01-05 at 14:17 +0000, Andrew Cooper wrote:
> On 05/01/16 14:13, Ian Campbell wrote:
> > On Tue, 2015-12-22 at 09:29 -0700, Jan Beulich wrote:
> > > > > > On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
> > > > --- a/xen/include/public/arch-x86/featureset.h
> > > > +++ b/xen/include/public/arch-x86/featureset.h
> > > > @@ -163,6 +163,7 @@
> > > >  
> > > >  /* Intel-defined CPU features, CPUID level 0x00000007:0.ebx, word
> > > > 5 */
> > > >  #define X86_FEATURE_FSGSBASE      ( 5*32+ 0) /* {RD,WR}{FS,GS}BASE
> > > > instructions */
> > > > +#define X86_FEATURE_TSC_ADJUST    ( 5*32+ 1) /* TSC_ADJUST MSR
> > > > available */
> > > This would probably better go into patch 1.
> > Tools would then see this defined twice with only patch 1 applied, and
> > since the value is actually different I think the compiler will
> > complain.
> > 
> > -#define X86_FEATURE_TSC_ADJUST   1 /* Tsc thread offset */
> > +#define X86_FEATURE_TSC_ADJUST    ( 5*32+ 1) /* TSC_ADJUST MSR
> > available */
> > 
> > The comment change seems to be a semantic one? Or was it wrong beofre?
> 
> Changing patch 1 won't affect the compilation of libxc.  Observe in the
> penultimate hunk that I also change the #include

Ah yes.

What about my comment on the comment changing?

> 
> ~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 03/31] xen/x86: Store antifeatures inverted in a featureset
  2015-12-22 17:03     ` Andrew Cooper
@ 2016-01-05 14:19       ` Ian Campbell
  2016-01-05 14:24         ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Ian Campbell @ 2016-01-05 14:19 UTC (permalink / raw)
  To: Andrew Cooper, Jan Beulich; +Cc: Xen-devel

On Tue, 2015-12-22 at 17:03 +0000, Andrew Cooper wrote:
> On 22/12/15 16:32, Jan Beulich wrote:
> > > > > On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
> > > --- /dev/null
> > > +++ b/xen/arch/x86/cpuid/cpuid-private.h
> > > @@ -0,0 +1,27 @@
> > > +#ifdef __XEN__
> > > +
> > > +#include <asm/cpufeature.h>
> > > +
> > > +#include <xen/lib.h>
> > > +
> > > +#else
> > > +
> > > +# error TODO for userspace
> > I suppose your intentions with this will become apparent in later
> > patches?
> 
> Everything in xen/arch/x86/cpuid/ is shared code between Xen and libxc,
> to avoid having different algorithms/structures between the hypervisor
> and toolstack.

I took the question to be "does a later patch in this series remove the
#error?".

Ian.

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 02/31] tools/libxc: Use public/featureset.h for cpuid policy generation
  2016-01-05 14:18         ` Ian Campbell
@ 2016-01-05 14:23           ` Andrew Cooper
  2016-01-05 15:02             ` Ian Campbell
  0 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2016-01-05 14:23 UTC (permalink / raw)
  To: Ian Campbell, Jan Beulich; +Cc: Ian Jackson, Tim Deegan, Xen-devel

On 05/01/16 14:18, Ian Campbell wrote:
> On Tue, 2016-01-05 at 14:17 +0000, Andrew Cooper wrote:
>> On 05/01/16 14:13, Ian Campbell wrote:
>>> On Tue, 2015-12-22 at 09:29 -0700, Jan Beulich wrote:
>>>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>>>> --- a/xen/include/public/arch-x86/featureset.h
>>>>> +++ b/xen/include/public/arch-x86/featureset.h
>>>>> @@ -163,6 +163,7 @@
>>>>>  
>>>>>  /* Intel-defined CPU features, CPUID level 0x00000007:0.ebx, word
>>>>> 5 */
>>>>>  #define X86_FEATURE_FSGSBASE      ( 5*32+ 0) /* {RD,WR}{FS,GS}BASE
>>>>> instructions */
>>>>> +#define X86_FEATURE_TSC_ADJUST    ( 5*32+ 1) /* TSC_ADJUST MSR
>>>>> available */
>>>> This would probably better go into patch 1.
>>> Tools would then see this defined twice with only patch 1 applied, and
>>> since the value is actually different I think the compiler will
>>> complain.
>>>
>>> -#define X86_FEATURE_TSC_ADJUST   1 /* Tsc thread offset */
>>> +#define X86_FEATURE_TSC_ADJUST    ( 5*32+ 1) /* TSC_ADJUST MSR
>>> available */
>>>
>>> The comment change seems to be a semantic one? Or was it wrong beofre?
>> Changing patch 1 won't affect the compilation of libxc.  Observe in the
>> penultimate hunk that I also change the #include
> Ah yes.
>
> What about my comment on the comment changing?

Ah yes - the changes are just semantic.  Also observe that the same hunk
also modifies the libxc macros to modulo 32.

In the end, both the hypervisor and libxc are dealing with
hardware-specified bits in registers.  This patch is no resulting change
to behaviour.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 03/31] xen/x86: Store antifeatures inverted in a featureset
  2016-01-05 14:19       ` Ian Campbell
@ 2016-01-05 14:24         ` Andrew Cooper
  0 siblings, 0 replies; 123+ messages in thread
From: Andrew Cooper @ 2016-01-05 14:24 UTC (permalink / raw)
  To: Ian Campbell, Jan Beulich; +Cc: Xen-devel

On 05/01/16 14:19, Ian Campbell wrote:
> On Tue, 2015-12-22 at 17:03 +0000, Andrew Cooper wrote:
>> On 22/12/15 16:32, Jan Beulich wrote:
>>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>>> --- /dev/null
>>>> +++ b/xen/arch/x86/cpuid/cpuid-private.h
>>>> @@ -0,0 +1,27 @@
>>>> +#ifdef __XEN__
>>>> +
>>>> +#include <asm/cpufeature.h>
>>>> +
>>>> +#include <xen/lib.h>
>>>> +
>>>> +#else
>>>> +
>>>> +# error TODO for userspace
>>> I suppose your intentions with this will become apparent in later
>>> patches?
>> Everything in xen/arch/x86/cpuid/ is shared code between Xen and libxc,
>> to avoid having different algorithms/structures between the hypervisor
>> and toolstack.
> I took the question to be "does a later patch in this series remove the
> #error?".

Yes - patch 12, although I am going to see about some reordering of the
series for v2.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 02/31] tools/libxc: Use public/featureset.h for cpuid policy generation
  2016-01-05 14:23           ` Andrew Cooper
@ 2016-01-05 15:02             ` Ian Campbell
  2016-01-05 15:42               ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Ian Campbell @ 2016-01-05 15:02 UTC (permalink / raw)
  To: Andrew Cooper, Jan Beulich; +Cc: Ian Jackson, Tim Deegan, Xen-devel

On Tue, 2016-01-05 at 14:23 +0000, Andrew Cooper wrote:
> On 05/01/16 14:18, Ian Campbell wrote:
> > On Tue, 2016-01-05 at 14:17 +0000, Andrew Cooper wrote:
> > > On 05/01/16 14:13, Ian Campbell wrote:
> > > > On Tue, 2015-12-22 at 09:29 -0700, Jan Beulich wrote:
> > > > > > > > On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
> > > > > > --- a/xen/include/public/arch-x86/featureset.h
> > > > > > +++ b/xen/include/public/arch-x86/featureset.h
> > > > > > @@ -163,6 +163,7 @@
> > > > > >  
> > > > > >  /* Intel-defined CPU features, CPUID level 0x00000007:0.ebx,
> > > > > > word
> > > > > > 5 */
> > > > > >  #define X86_FEATURE_FSGSBASE      ( 5*32+ 0) /*
> > > > > > {RD,WR}{FS,GS}BASE
> > > > > > instructions */
> > > > > > +#define X86_FEATURE_TSC_ADJUST    ( 5*32+ 1) /* TSC_ADJUST MSR
> > > > > > available */
> > > > > This would probably better go into patch 1.
> > > > Tools would then see this defined twice with only patch 1 applied,
> > > > and
> > > > since the value is actually different I think the compiler will
> > > > complain.
> > > > 
> > > > -#define X86_FEATURE_TSC_ADJUST   1 /* Tsc thread offset */
> > > > +#define X86_FEATURE_TSC_ADJUST    ( 5*32+ 1) /* TSC_ADJUST MSR
> > > > available */
> > > > 
> > > > The comment change seems to be a semantic one? Or was it wrong
> > > > beofre?
> > > Changing patch 1 won't affect the compilation of libxc.  Observe in
> > > the
> > > penultimate hunk that I also change the #include
> > Ah yes.
> > 
> > What about my comment on the comment changing?
> 
> Ah yes - the changes are just semantic.  Also observe that the same hunk
> also modifies the libxc macros to modulo 32.

I'm not talking about the value at all, since I realised that the masking
makes the values the same. I'm talking about the /* comment */ next to it
which has also changed.

> In the end, both the hypervisor and libxc are dealing with
> hardware-specified bits in registers.  This patch is no resulting change
> to behaviour.

But do "Tsc thread offset" and "TSC_ADJUST MSR available" mean the same
thing? Or was "Tsc thread offset" previously actively wrong or misleading
in some way?

Ian. 


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 12/31] tools: Utility for dealing with featuresets
  2015-12-16 21:24 ` [PATCH RFC 12/31] tools: Utility for dealing with featuresets Andrew Cooper
@ 2016-01-05 15:17   ` Ian Campbell
  2016-01-05 16:14     ` Andrew Cooper
  2016-01-06 10:40   ` Ian Campbell
  1 sibling, 1 reply; 123+ messages in thread
From: Ian Campbell @ 2016-01-05 15:17 UTC (permalink / raw)
  To: Andrew Cooper, Xen-devel; +Cc: Wei Liu, Ian Jackson

On Wed, 2015-12-16 at 21:24 +0000, Andrew Cooper wrote:
> It is able to reports the current featuresets; both the static masks and
> dynamic featuresets from Xen, or to decode an arbitrary featureset into
> `/proc/cpuinfo` style strings.

More than adding a utility does this not also arrange for a whole bunch of
new functionality to be compiled into libxc? That's worth mentioning here.

And doesn't it do so in a non-library namespaced way (e.g.
with calculate_featuresets() and decode_featureset() being exposed by the
library)?

Granted there's lots of that sort of thing already, but should we really be
making it worse?

libelf avoids this by namespacing itself as a quasi-standalone library in
both the tools and hypervisor contexts.

> 
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> CC: Ian Campbell <Ian.Campbell@citrix.com>
> CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
> CC: Wei Liu <wei.liu2@citrix.com>
> ---
>  .gitignore                         |   1 +
>  tools/libxc/Makefile               |   6 +
>  tools/misc/Makefile                |   6 +
>  tools/misc/xen-cpuid.c             | 392
> +++++++++++++++++++++++++++++++++++++
>  xen/arch/x86/cpuid/cpuid-private.h |   9 +-
>  5 files changed, 413 insertions(+), 1 deletion(-)
>  create mode 100644 tools/misc/xen-cpuid.c
> 
> diff --git a/.gitignore b/.gitignore
> index 9ead7c4..63944b5 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -167,6 +167,7 @@ tools/misc/cpuperf/cpuperf-perfcntr
>  tools/misc/cpuperf/cpuperf-xen
>  tools/misc/xc_shadow
>  tools/misc/xen_cpuperf
> +tools/misc/xen-cpuid
>  tools/misc/xen-detect
>  tools/misc/xen-tmem-list-parse
>  tools/misc/xenperf
> diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
> index a0f899b..83547e1 100644
> --- a/tools/libxc/Makefile
> +++ b/tools/libxc/Makefile
> @@ -79,6 +79,12 @@ GUEST_SRCS-y += $(ELF_SRCS-y)
>  $(patsubst %.c,%.o,$(ELF_SRCS-y)): CFLAGS += -Wno-pointer-sign
>  $(patsubst %.c,%.opic,$(ELF_SRCS-y)): CFLAGS += -Wno-pointer-sign
>  
> +ifeq ($(CONFIG_X86),y)
> +vpath %.c ../../xen/arch/x86/cpuid
> +CFLAGS += -I../../xen/arch/x86/cpuid
> +CTRL_SRCS-y += cpuid.c
> +endif
> +
>  # new domain builder
>  GUEST_SRCS-y                 += xc_dom_core.c xc_dom_boot.c
>  GUEST_SRCS-y                 += xc_dom_elfloader.c
> diff --git a/tools/misc/Makefile b/tools/misc/Makefile
> index c4490f3..eb7649d 100644
> --- a/tools/misc/Makefile
> +++ b/tools/misc/Makefile
> @@ -9,6 +9,7 @@ CFLAGS += $(CFLAGS_xeninclude)
>  CFLAGS += $(CFLAGS_libxenstore)
>  
>  # Everything to be installed in regular bin/
> +INSTALL_BIN-$(CONFIG_X86)      += xen-cpuid
>  INSTALL_BIN-$(CONFIG_X86)      += xen-detect
>  INSTALL_BIN                    += xencons
>  INSTALL_BIN                    += xencov_split
> @@ -67,6 +68,11 @@ clean:
>  .PHONY: distclean
>  distclean: clean
>  
> +xen-cpuid.o: CFLAGS += -I$(XEN_ROOT)/xen/arch/x86/cpuid
> +xen-cpuid.o: CFLAGS += -I$(XEN_ROOT)/tools/libxc
> +xen-cpuid: xen-cpuid.o
> +	$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS)
> +
>  xen-hvmctx: xen-hvmctx.o
>  	$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS)
>  
> diff --git a/tools/misc/xen-cpuid.c b/tools/misc/xen-cpuid.c
> new file mode 100644
> index 0000000..e0cd6bb
> --- /dev/null
> +++ b/tools/misc/xen-cpuid.c
> @@ -0,0 +1,392 @@
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <err.h>
> +#include <getopt.h>
> +#include <string.h>
> +
> +#include <xenctrl.h>
> +#include "cpuid-private.h"
> +
> +static uint32_t nr_features = XEN_NR_FEATURESET_ENTRIES;
> +
> +static const char *str_1d[32] =

If these are to be Xen's names could they come from the common cpuid
location such that other users of these interfaces (including Xen itself)
can use consistent names?

(and then naturally be part of the autogeneration which has been discussed)
> + option_error:
> +            printf("Usage: %s [ info | detail | <featureset>* ]\n", argv[0]);

What format does <featureset> take?


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 08/31] tools/stubs: Expose host featureset to userspace
  2015-12-16 21:24 ` [PATCH RFC 08/31] tools/stubs: Expose host featureset to userspace Andrew Cooper
@ 2016-01-05 15:36   ` Ian Campbell
  2016-01-05 15:59     ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Ian Campbell @ 2016-01-05 15:36 UTC (permalink / raw)
  To: Andrew Cooper, Xen-devel; +Cc: Wei Liu, Ian Jackson, Rob Hoes, David Scott

On Wed, 2015-12-16 at 21:24 +0000, Andrew Cooper wrote:
> diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c
> index c613545..4d7af3d 100644
> --- a/tools/libxc/xc_misc.c
> +++ b/tools/libxc/xc_misc.c
> @@ -718,6 +718,33 @@ int xc_hvm_inject_trap(
>      return rc;
>  }
>  
> +int xc_get_featureset(xc_interface *xch, uint32_t index,
> +                      uint32_t *nr_features, uint32_t *featureset)

This looks like a valid binding to the hypercall iface, so once that is
agreed this LGTM.

> diff --git a/tools/ocaml/libs/xc/xenctrl_stubs.c
> b/tools/ocaml/libs/xc/xenctrl_stubs.c
> index b7de615..a47473b 100644
> --- a/tools/ocaml/libs/xc/xenctrl_stubs.c
> +++ b/tools/ocaml/libs/xc/xenctrl_stubs.c
> @@ -1220,6 +1220,41 @@ CAMLprim value
> stub_xc_domain_deassign_device(value xch, value domid, value desc
>  	CAMLreturn(Val_unit);
>  }
>  
> +CAMLprim value stub_xc_get_featureset(value xch, value idx)
> +{
> +	CAMLparam2(xch, idx);
> +	CAMLlocal1(bitmap_val);
> +
> +	/* Safe, because of the global ocaml lock. */
> +	static uint32_t fs_len;
> +
> +	if (fs_len == 0)
> +	{
> +		int ret = xc_get_featureset(_H(xch), 0, &fs_len, NULL);
> +
> +		if (ret || (fs_len == 0))
> +			failwith_xc(_H(xch));
> +	}

This confuses me because I had thought when reading the previous patch that
the output nr_features would depend on the specific index, is that not the
case? Maybe this is just a hypercall docs fix?



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 13/31] tools/libxc: Wire a featureset through to cpuid policy logic
  2015-12-16 21:24 ` [PATCH RFC 13/31] tools/libxc: Wire a featureset through to cpuid policy logic Andrew Cooper
@ 2016-01-05 15:42   ` Ian Campbell
  2016-01-05 16:20     ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Ian Campbell @ 2016-01-05 15:42 UTC (permalink / raw)
  To: Andrew Cooper, Xen-devel; +Cc: Wei Liu, Ian Jackson

On Wed, 2015-12-16 at 21:24 +0000, Andrew Cooper wrote:
> Later changes will cause the cpuid generation logic to seed their
> information
> from a featureset.  This patch adds the infrastructure to specify a
> featureset, and will obtain the appropriate default from Xen if omitted.
> 
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> CC: Ian Campbell <Ian.Campbell@citrix.com>
> CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
> CC: Wei Liu <wei.liu2@citrix.com>
> ---
>  tools/libxc/include/xenctrl.h |  3 ++
>  tools/libxc/xc_cpuid_x86.c    | 90
> ++++++++++++++++++++++++++++++++++++++-----
>  2 files changed, 84 insertions(+), 9 deletions(-)
> 
> diff --git a/tools/libxc/include/xenctrl.h
> b/tools/libxc/include/xenctrl.h
> index 27e1f45..b44aec7 100644
> --- a/tools/libxc/include/xenctrl.h
> +++ b/tools/libxc/include/xenctrl.h
> @@ -2211,6 +2211,9 @@ int xc_cpuid_set(xc_interface *xch,
>                   char **config_transformed);
>  int xc_cpuid_apply_policy(xc_interface *xch,
>                            domid_t domid);
> +int xc_cpuid_apply_policy_with_featureset(xc_interface *xch, domid_t domid,
> +                                          uint32_t *featureset,
> +                                          unsigned int nr_features);

We should aim to eventually only have one apply policy interface here not
two, unless there is some good reason why xc_cpuid_apply_policy() should
remain?

AIUI passing featureset==NULL is going to be semantically identical to the
old interface, so I think we should just go with adding the new parameters
to the existing function.

> @@ -103,6 +109,32 @@ static int get_cpuid_domain_info(xc_interface *xch, domid_t domid,
>      info->hvm = di.hvm;
>      info->pvh = di.pvh;
>  
> +    /* Get featureset information. */
> +    rc = xc_get_featureset(xch, XEN_SYSCTL_featureset_host,
> +                           &host_nr_features, NULL);
> +    if ( rc )
> +        return rc;
> +
> +    if ( host_nr_features < XEN_FEATURESET_7c0 )
> +        return -EINVAL;

Could we assert this? I mean if Xen and libxc don't agree on this then
something went pretty wrong during the dev window.

> +
> +    info->featureset = calloc(host_nr_features, sizeof(*info->featureset));
> +    if ( !info->featureset )
> +        return -ENOMEM;
> +
> +    info->nr_features = host_nr_features;
> +
> +    if ( featureset )
> +    {
> +        memcpy(info->featureset, featureset,
> +               min(host_nr_features, nr_features) * sizeof(*info->featureset));
> +
> +        /* Check for trucated set bits. */

"truncated"

Ian.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 02/31] tools/libxc: Use public/featureset.h for cpuid policy generation
  2016-01-05 15:02             ` Ian Campbell
@ 2016-01-05 15:42               ` Andrew Cooper
  2016-01-05 16:09                 ` Ian Campbell
  0 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2016-01-05 15:42 UTC (permalink / raw)
  To: Ian Campbell, Jan Beulich; +Cc: Ian Jackson, Tim Deegan, Xen-devel

On 05/01/16 15:02, Ian Campbell wrote:
> On Tue, 2016-01-05 at 14:23 +0000, Andrew Cooper wrote:
>> On 05/01/16 14:18, Ian Campbell wrote:
>>> On Tue, 2016-01-05 at 14:17 +0000, Andrew Cooper wrote:
>>>> On 05/01/16 14:13, Ian Campbell wrote:
>>>>> On Tue, 2015-12-22 at 09:29 -0700, Jan Beulich wrote:
>>>>>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>>>>>> --- a/xen/include/public/arch-x86/featureset.h
>>>>>>> +++ b/xen/include/public/arch-x86/featureset.h
>>>>>>> @@ -163,6 +163,7 @@
>>>>>>>  
>>>>>>>  /* Intel-defined CPU features, CPUID level 0x00000007:0.ebx,
>>>>>>> word
>>>>>>> 5 */
>>>>>>>  #define X86_FEATURE_FSGSBASE      ( 5*32+ 0) /*
>>>>>>> {RD,WR}{FS,GS}BASE
>>>>>>> instructions */
>>>>>>> +#define X86_FEATURE_TSC_ADJUST    ( 5*32+ 1) /* TSC_ADJUST MSR
>>>>>>> available */
>>>>>> This would probably better go into patch 1.
>>>>> Tools would then see this defined twice with only patch 1 applied,
>>>>> and
>>>>> since the value is actually different I think the compiler will
>>>>> complain.
>>>>>
>>>>> -#define X86_FEATURE_TSC_ADJUST   1 /* Tsc thread offset */
>>>>> +#define X86_FEATURE_TSC_ADJUST    ( 5*32+ 1) /* TSC_ADJUST MSR
>>>>> available */
>>>>>
>>>>> The comment change seems to be a semantic one? Or was it wrong
>>>>> beofre?
>>>> Changing patch 1 won't affect the compilation of libxc.  Observe in
>>>> the
>>>> penultimate hunk that I also change the #include
>>> Ah yes.
>>>
>>> What about my comment on the comment changing?
>> Ah yes - the changes are just semantic.  Also observe that the same hunk
>> also modifies the libxc macros to modulo 32.
> I'm not talking about the value at all, since I realised that the masking
> makes the values the same. I'm talking about the /* comment */ next to it
> which has also changed.
>
>> In the end, both the hypervisor and libxc are dealing with
>> hardware-specified bits in registers.  This patch is no resulting change
>> to behaviour.
> But do "Tsc thread offset" and "TSC_ADJUST MSR available" mean the same
> thing? Or was "Tsc thread offset" previously actively wrong or misleading
> in some way?

The latter is the accurate meaning of the bit in cpuid.  The former is
misleading IMO, and covers one use for it in a Linux world.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 14/31] tools/libxc: Use featureset rather than guesswork
  2015-12-16 21:24 ` [PATCH RFC 14/31] tools/libxc: Use featureset rather than guesswork Andrew Cooper
@ 2016-01-05 15:54   ` Ian Campbell
  2016-01-05 16:22     ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Ian Campbell @ 2016-01-05 15:54 UTC (permalink / raw)
  To: Andrew Cooper, Xen-devel; +Cc: Wei Liu, Ian Jackson

On Wed, 2015-12-16 at 21:24 +0000, Andrew Cooper wrote:
> It is conceptually wrong to base a VM's featureset on the features
> visible to
> the toolstack which happens to construct it.
> 
> Instead, the featureset used is either an explicit one passed by the
> toolstack, or the default which Xen believes it can give to the guest.
> 
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> CC: Ian Campbell <Ian.Campbell@citrix.com>
> CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
> CC: Wei Liu <wei.liu2@citrix.com>
> ---
>  tools/libxc/xc_cpuid_x86.c | 229 +++++++++++++------------------------
> --------
>  1 file changed, 64 insertions(+), 165 deletions(-)
> 
> diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
> index 8bd3126..3f39306 100644
> --- a/tools/libxc/xc_cpuid_x86.c
> +++ b/tools/libxc/xc_cpuid_x86.c
> @@ -24,6 +24,7 @@
>  #include "xc_private.h"
>  #include <xen/arch-x86/featureset.h>
>  #include <xen/hvm/params.h>
> +#include <xen/sysctl.h>
>  
>  #define bitmaskof(idx)      (1u << ((idx) & 31))
>  #define clear_bit(idx, dst) ((dst) &= ~bitmaskof(idx))
> @@ -211,37 +212,19 @@ static void amd_xc_cpuid_policy(xc_interface *xch,
>              regs[0] = DEF_MAX_AMDEXT;
>          break;
>  
> -    case 0x80000001: {
> +    case 0x80000001:
>          if ( !info->pae )
>              clear_bit(X86_FEATURE_PAE, regs[3]);

This (and the others which actually change in this patch) are correct
because the locally defined clear_bit (contrary to what one might usually
expect) includes masking off the lower bits to get the offset in the given
word, is that right?

That confused me a lot until I spotted the clear_bit in the context above.
What do you think about renaming it to clear_feature, or something else
without the false expectation? Just thought I'd mention it having scratched
my head for a bit ;-), feel free to say no.

Ian.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 08/31] tools/stubs: Expose host featureset to userspace
  2016-01-05 15:36   ` Ian Campbell
@ 2016-01-05 15:59     ` Andrew Cooper
  2016-01-05 16:09       ` Ian Campbell
  0 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2016-01-05 15:59 UTC (permalink / raw)
  To: Ian Campbell, Xen-devel; +Cc: Wei Liu, Ian Jackson, Rob Hoes, David Scott

On 05/01/16 15:36, Ian Campbell wrote:
> On Wed, 2015-12-16 at 21:24 +0000, Andrew Cooper wrote:
>> diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c
>> index c613545..4d7af3d 100644
>> --- a/tools/libxc/xc_misc.c
>> +++ b/tools/libxc/xc_misc.c
>> @@ -718,6 +718,33 @@ int xc_hvm_inject_trap(
>>      return rc;
>>  }
>>  
>> +int xc_get_featureset(xc_interface *xch, uint32_t index,
>> +                      uint32_t *nr_features, uint32_t *featureset)
> This looks like a valid binding to the hypercall iface, so once that is
> agreed this LGTM.
>
>> diff --git a/tools/ocaml/libs/xc/xenctrl_stubs.c
>> b/tools/ocaml/libs/xc/xenctrl_stubs.c
>> index b7de615..a47473b 100644
>> --- a/tools/ocaml/libs/xc/xenctrl_stubs.c
>> +++ b/tools/ocaml/libs/xc/xenctrl_stubs.c
>> @@ -1220,6 +1220,41 @@ CAMLprim value
>> stub_xc_domain_deassign_device(value xch, value domid, value desc
>>  	CAMLreturn(Val_unit);
>>  }
>>  
>> +CAMLprim value stub_xc_get_featureset(value xch, value idx)
>> +{
>> +	CAMLparam2(xch, idx);
>> +	CAMLlocal1(bitmap_val);
>> +
>> +	/* Safe, because of the global ocaml lock. */
>> +	static uint32_t fs_len;
>> +
>> +	if (fs_len == 0)
>> +	{
>> +		int ret = xc_get_featureset(_H(xch), 0, &fs_len, NULL);
>> +
>> +		if (ret || (fs_len == 0))
>> +			failwith_xc(_H(xch));
>> +	}
> This confuses me because I had thought when reading the previous patch that
> the output nr_features would depend on the specific index, is that not the
> case? Maybe this is just a hypercall docs fix?

nr_features is compile-time-constant in Xen, and every featureset handed
back will be of that length.

It is expected to grow given new changes to Xen, but won't change at
runtime.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 15/31] x86: Generate deep dependencies of x86 features
  2015-12-16 21:24 ` [PATCH RFC 15/31] x86: Generate deep dependencies of x86 features Andrew Cooper
@ 2016-01-05 16:03   ` Ian Campbell
  2016-01-05 16:42     ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Ian Campbell @ 2016-01-05 16:03 UTC (permalink / raw)
  To: Andrew Cooper, Xen-devel; +Cc: Wei Liu, Ian Jackson, Jan Beulich

On Wed, 2015-12-16 at 21:24 +0000, Andrew Cooper wrote:
> Some features depend on other features.  Working out and maintaining the exact
> dependency tree is complicated, so it is expressed in script form instead.
> 
> `gen-feature-deps.py` parses 'xen/include/public/arch-x86/featureset.h' (To
> obtain some literal names conforming to the API), contains some single-step
> dependency information, performs some number crunching, and writes autogen.c
> to make the results of the number crunching available.

In libxl we prepend a _ to autogenerated file names, may as well do the
same here I guess.

> In this case, it writes out deep dependency infomarion, to allow featureset

"information"
> code to find all eventual features cleared in a dependency chain.
> 
> To be able to compile for userspace, libxc's bitmap macros are made more
> generic (to match Xen's), and accept a void * instead of unsigned long *.

Can we do this in a separate patch please.

IIRC void * arithmetic is a gcc (and presumably clang) extension, which we
can specify for Xen itself, but I'm not sure about libxc (cf: recent
discussions about building stuff for Windows).

What actually breaks with the existing definitions?

> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> CC: Jan Beulich <JBeulich@suse.com>
> CC: Ian Campbell <Ian.Campbell@citrix.com>
> CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
> CC: Wei Liu <wei.liu2@citrix.com>
> 
> TODO: The generation of autogen.c now means that libxc needs to be compiled
> after the hypervisor, as the vpath doesn't convey the generation information.
> I need to find a way to fix this.

I'd be inclined to do the autogeneration twice with the output being
outside the shared directory or gaining a (tools|xen)_ prefix.

It's a bit wasteful to do it twice but anything else would add an
undesirable linkage between tools and hypervisor build I think. I'm certain
we don't want to commit the generated files.

> diff --git a/xen/arch/x86/cpuid/cpuid-private.h
> b/xen/arch/x86/cpuid/cpuid-private.h
> index 1c92ee4..438f5d2 100644
> --- a/xen/arch/x86/cpuid/cpuid-private.h
> +++ b/xen/arch/x86/cpuid/cpuid-private.h
> @@ -64,6 +64,24 @@ extern const uint32_t
> pv_featuremask[XEN_NR_FEATURESET_ENTRIES];
>  extern const uint32_t hvm_shadow_featuremask[XEN_NR_FEATURESET_ENTRIES];
>  extern const uint32_t hvm_hap_featuremask[XEN_NR_FEATURESET_ENTRIES];
>  
> +/* A featureset with a tag. */
> +struct tagged_featureset
> +{
> +    uint32_t tag;
> +    uint32_t fs[XEN_NR_FEATURESET_ENTRIES];
> +};
> +
> +/* Sparse feature matrix identifying all features which depend on a
> feature. */
> +extern const struct tagged_featureset deep_deps[];

This'll be XEN_NR_FEATURESET_ENTRIES^2 entries? How big is that getting
OOI?

> diff --git a/xen/arch/x86/cpuid/gen-feature-deps.py b/xen/arch/x86/cpuid/gen-feature-deps.py
> new file mode 100755
> index 0000000..f0ecbba
> --- /dev/null
> +++ b/xen/arch/x86/cpuid/gen-feature-deps.py
> @@ -0,0 +1,152 @@
> +#!/usr/bin/env python
> +import sys, os, os.path as path, re
> +
> +names = {}
> +
> +with open(path.join(os.environ["XEN_ROOT"],
> +                    "xen/include/public/arch-x86/featureset.h")) as f:

I'd weakly prefer all the input and output paths to come from the command
line.

I have a feeling you are planning to redo a bunch of this (or if not then
Jan was requesting something more structured which may or may not cause big
changes here), so I'll leave the actual review for now.

> +
> +        # Expected duplicate symbols.  Discard
> +        if name in ('3DNOW_ALT', ):
> +            continue

OOI how does this arise?



_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 19/31] tools/libxc: Sanitise guest featuresets
  2015-12-16 21:24 ` [PATCH RFC 19/31] tools/libxc: Sanitise guest featuresets Andrew Cooper
@ 2016-01-05 16:05   ` Ian Campbell
  0 siblings, 0 replies; 123+ messages in thread
From: Ian Campbell @ 2016-01-05 16:05 UTC (permalink / raw)
  To: Andrew Cooper, Xen-devel; +Cc: Wei Liu, Ian Jackson

On Wed, 2015-12-16 at 21:24 +0000, Andrew Cooper wrote:
> When generating a VM featureset, clearing individual features is
> problematic
> if a feature has dependent features.
> 
> Instead of disabling individual features, collect all disabling together
> in
> sanitise_featureset(), and perform deep dependency removal on the result,
> to
> remove all impacted features.
> 
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
> CC: Ian Campbell <Ian.Campbell@citrix.com>
> CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
> CC: Wei Liu <wei.liu2@citrix.com>
> ---
>  tools/libxc/xc_cpuid_x86.c | 144 +++++++++++++++++++++----------------
> --------
>  1 file changed, 67 insertions(+), 77 deletions(-)
> 
> diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
> index 3f39306..6c8995f 100644
> --- a/tools/libxc/xc_cpuid_x86.c
> +++ b/tools/libxc/xc_cpuid_x86.c
> @@ -21,14 +21,15 @@
>  
>  #include <stdlib.h>
>  #include <stdbool.h>
> +#include <limits.h>
>  #include "xc_private.h"
> -#include <xen/arch-x86/featureset.h>
> +#include "cpuid-private.h"
>  #include <xen/hvm/params.h>
>  #include <xen/sysctl.h>
>  
>  #define bitmaskof(idx)      (1u << ((idx) & 31))
> -#define clear_bit(idx, dst) ((dst) &= ~bitmaskof(idx))
> -#define set_bit(idx, dst)   ((dst) |=  bitmaskof(idx))
> +#define clear_feature(idx, dst) ((dst) &= ~bitmaskof(idx))
> +#define set_feature(idx, dst)   ((dst) |=  bitmaskof(idx))

Heh.


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 08/31] tools/stubs: Expose host featureset to userspace
  2016-01-05 15:59     ` Andrew Cooper
@ 2016-01-05 16:09       ` Ian Campbell
  2016-01-05 16:19         ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Ian Campbell @ 2016-01-05 16:09 UTC (permalink / raw)
  To: Andrew Cooper, Xen-devel; +Cc: Wei Liu, Ian Jackson, Rob Hoes, David Scott

On Tue, 2016-01-05 at 15:59 +0000, Andrew Cooper wrote:
> On 05/01/16 15:36, Ian Campbell wrote:
> > On Wed, 2015-12-16 at 21:24 +0000, Andrew Cooper wrote:
> > > diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c
> > > index c613545..4d7af3d 100644
> > > --- a/tools/libxc/xc_misc.c
> > > +++ b/tools/libxc/xc_misc.c
> > > @@ -718,6 +718,33 @@ int xc_hvm_inject_trap(
> > >      return rc;
> > >  }
> > >  
> > > +int xc_get_featureset(xc_interface *xch, uint32_t index,
> > > +                      uint32_t *nr_features, uint32_t *featureset)
> > This looks like a valid binding to the hypercall iface, so once that is
> > agreed this LGTM.
> > 
> > > diff --git a/tools/ocaml/libs/xc/xenctrl_stubs.c
> > > b/tools/ocaml/libs/xc/xenctrl_stubs.c
> > > index b7de615..a47473b 100644
> > > --- a/tools/ocaml/libs/xc/xenctrl_stubs.c
> > > +++ b/tools/ocaml/libs/xc/xenctrl_stubs.c
> > > @@ -1220,6 +1220,41 @@ CAMLprim value
> > > stub_xc_domain_deassign_device(value xch, value domid, value desc
> > >  	CAMLreturn(Val_unit);
> > >  }
> > >  
> > > +CAMLprim value stub_xc_get_featureset(value xch, value idx)
> > > +{
> > > +	CAMLparam2(xch, idx);
> > > +	CAMLlocal1(bitmap_val);
> > > +
> > > +	/* Safe, because of the global ocaml lock. */
> > > +	static uint32_t fs_len;
> > > +
> > > +	if (fs_len == 0)
> > > +	{
> > > +		int ret = xc_get_featureset(_H(xch), 0, &fs_len,
> > > NULL);
> > > +
> > > +		if (ret || (fs_len == 0))
> > > +			failwith_xc(_H(xch));
> > > +	}
> > This confuses me because I had thought when reading the previous patch
> > that
> > the output nr_features would depend on the specific index, is that not
> > the
> > case? Maybe this is just a hypercall docs fix?
> 
> nr_features is compile-time-constant in Xen, and every featureset handed
> back will be of that length.

IOW if the featureset given to the hypercall is NULL then index is ignored?
Worth documenting.

> It is expected to grow given new changes to Xen, but won't change at
> runtime.

And we never expect any index to need a different length to all the others?

Ian.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 02/31] tools/libxc: Use public/featureset.h for cpuid policy generation
  2016-01-05 15:42               ` Andrew Cooper
@ 2016-01-05 16:09                 ` Ian Campbell
  0 siblings, 0 replies; 123+ messages in thread
From: Ian Campbell @ 2016-01-05 16:09 UTC (permalink / raw)
  To: Andrew Cooper, Jan Beulich; +Cc: Ian Jackson, Tim Deegan, Xen-devel

On Tue, 2016-01-05 at 15:42 +0000, Andrew Cooper wrote:
> On 05/01/16 15:02, Ian Campbell wrote:
> > On Tue, 2016-01-05 at 14:23 +0000, Andrew Cooper wrote:
> > > On 05/01/16 14:18, Ian Campbell wrote:
> > > > On Tue, 2016-01-05 at 14:17 +0000, Andrew Cooper wrote:
> > > > > On 05/01/16 14:13, Ian Campbell wrote:
> > > > > > On Tue, 2015-12-22 at 09:29 -0700, Jan Beulich wrote:
> > > > > > > > > > On 16.12.15 at 22:24, <andrew.cooper3@citrix.com>
> > > > > > > > > > wrote:
> > > > > > > > --- a/xen/include/public/arch-x86/featureset.h
> > > > > > > > +++ b/xen/include/public/arch-x86/featureset.h
> > > > > > > > @@ -163,6 +163,7 @@
> > > > > > > >  
> > > > > > > >  /* Intel-defined CPU features, CPUID level
> > > > > > > > 0x00000007:0.ebx,
> > > > > > > > word
> > > > > > > > 5 */
> > > > > > > >  #define X86_FEATURE_FSGSBASE      ( 5*32+ 0) /*
> > > > > > > > {RD,WR}{FS,GS}BASE
> > > > > > > > instructions */
> > > > > > > > +#define X86_FEATURE_TSC_ADJUST    ( 5*32+ 1) /* TSC_ADJUST
> > > > > > > > MSR
> > > > > > > > available */
> > > > > > > This would probably better go into patch 1.
> > > > > > Tools would then see this defined twice with only patch 1
> > > > > > applied,
> > > > > > and
> > > > > > since the value is actually different I think the compiler will
> > > > > > complain.
> > > > > > 
> > > > > > -#define X86_FEATURE_TSC_ADJUST   1 /* Tsc thread offset */
> > > > > > +#define X86_FEATURE_TSC_ADJUST    ( 5*32+ 1) /* TSC_ADJUST MSR
> > > > > > available */
> > > > > > 
> > > > > > The comment change seems to be a semantic one? Or was it wrong
> > > > > > beofre?
> > > > > Changing patch 1 won't affect the compilation of libxc.  Observe
> > > > > in
> > > > > the
> > > > > penultimate hunk that I also change the #include
> > > > Ah yes.
> > > > 
> > > > What about my comment on the comment changing?
> > > Ah yes - the changes are just semantic.  Also observe that the same
> > > hunk
> > > also modifies the libxc macros to modulo 32.
> > I'm not talking about the value at all, since I realised that the
> > masking
> > makes the values the same. I'm talking about the /* comment */ next to
> > it
> > which has also changed.
> > 
> > > In the end, both the hypervisor and libxc are dealing with
> > > hardware-specified bits in registers.  This patch is no resulting
> > > change
> > > to behaviour.
> > But do "Tsc thread offset" and "TSC_ADJUST MSR available" mean the same
> > thing? Or was "Tsc thread offset" previously actively wrong or
> > misleading
> > in some way?
> 
> The latter is the accurate meaning of the bit in cpuid.  The former is
> misleading IMO, and covers one use for it in a Linux world.

Thanks, I just wanted to be sure it was an intentional change and not e.g.
a cut-and-paste mistake.

Ian.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 12/31] tools: Utility for dealing with featuresets
  2016-01-05 15:17   ` Ian Campbell
@ 2016-01-05 16:14     ` Andrew Cooper
  2016-01-05 16:34       ` Ian Campbell
  0 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2016-01-05 16:14 UTC (permalink / raw)
  To: Ian Campbell, Xen-devel; +Cc: Wei Liu, Ian Jackson

On 05/01/16 15:17, Ian Campbell wrote:
> On Wed, 2015-12-16 at 21:24 +0000, Andrew Cooper wrote:
>> It is able to reports the current featuresets; both the static masks and
>> dynamic featuresets from Xen, or to decode an arbitrary featureset into
>> `/proc/cpuinfo` style strings.
> More than adding a utility does this not also arrange for a whole bunch of
> new functionality to be compiled into libxc? That's worth mentioning here.

It is almost all just data.  Only a single (trivial) function at
present.  But yes - it is worth mentioning.

>
> And doesn't it do so in a non-library namespaced way (e.g.
> with calculate_featuresets() and decode_featureset() being exposed by the
> library)?

calculate_featuresets() is hypervisor-only code and not included by this
change, and decode_featureset() is a local function to the utility.

>
> Granted there's lots of that sort of thing already, but should we really be
> making it worse?
>
> libelf avoids this by namespacing itself as a quasi-standalone library in
> both the tools and hypervisor contexts.

Nothing from the shared .c files is expected to be exposed in the API. 
The guts of xc_cpuid_policy() end up using it, but that is an
implementation detail.

I was also looking to avoid extraneous namespacing in Xen.  I am open to
suggestions here, but the only way to get at the definitions is via
cpuid-private.h

>
>> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
>> ---
>> CC: Ian Campbell <Ian.Campbell@citrix.com>
>> CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
>> CC: Wei Liu <wei.liu2@citrix.com>
>> ---
>>  .gitignore                         |   1 +
>>  tools/libxc/Makefile               |   6 +
>>  tools/misc/Makefile                |   6 +
>>  tools/misc/xen-cpuid.c             | 392
>> +++++++++++++++++++++++++++++++++++++
>>  xen/arch/x86/cpuid/cpuid-private.h |   9 +-
>>  5 files changed, 413 insertions(+), 1 deletion(-)
>>  create mode 100644 tools/misc/xen-cpuid.c
>>
>> diff --git a/.gitignore b/.gitignore
>> index 9ead7c4..63944b5 100644
>> --- a/.gitignore
>> +++ b/.gitignore
>> @@ -167,6 +167,7 @@ tools/misc/cpuperf/cpuperf-perfcntr
>>  tools/misc/cpuperf/cpuperf-xen
>>  tools/misc/xc_shadow
>>  tools/misc/xen_cpuperf
>> +tools/misc/xen-cpuid
>>  tools/misc/xen-detect
>>  tools/misc/xen-tmem-list-parse
>>  tools/misc/xenperf
>> diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile
>> index a0f899b..83547e1 100644
>> --- a/tools/libxc/Makefile
>> +++ b/tools/libxc/Makefile
>> @@ -79,6 +79,12 @@ GUEST_SRCS-y += $(ELF_SRCS-y)
>>  $(patsubst %.c,%.o,$(ELF_SRCS-y)): CFLAGS += -Wno-pointer-sign
>>  $(patsubst %.c,%.opic,$(ELF_SRCS-y)): CFLAGS += -Wno-pointer-sign
>>  
>> +ifeq ($(CONFIG_X86),y)
>> +vpath %.c ../../xen/arch/x86/cpuid
>> +CFLAGS += -I../../xen/arch/x86/cpuid
>> +CTRL_SRCS-y += cpuid.c
>> +endif
>> +
>>  # new domain builder
>>  GUEST_SRCS-y                 += xc_dom_core.c xc_dom_boot.c
>>  GUEST_SRCS-y                 += xc_dom_elfloader.c
>> diff --git a/tools/misc/Makefile b/tools/misc/Makefile
>> index c4490f3..eb7649d 100644
>> --- a/tools/misc/Makefile
>> +++ b/tools/misc/Makefile
>> @@ -9,6 +9,7 @@ CFLAGS += $(CFLAGS_xeninclude)
>>  CFLAGS += $(CFLAGS_libxenstore)
>>  
>>  # Everything to be installed in regular bin/
>> +INSTALL_BIN-$(CONFIG_X86)      += xen-cpuid
>>  INSTALL_BIN-$(CONFIG_X86)      += xen-detect
>>  INSTALL_BIN                    += xencons
>>  INSTALL_BIN                    += xencov_split
>> @@ -67,6 +68,11 @@ clean:
>>  .PHONY: distclean
>>  distclean: clean
>>  
>> +xen-cpuid.o: CFLAGS += -I$(XEN_ROOT)/xen/arch/x86/cpuid
>> +xen-cpuid.o: CFLAGS += -I$(XEN_ROOT)/tools/libxc
>> +xen-cpuid: xen-cpuid.o
>> +	$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS)
>> +
>>  xen-hvmctx: xen-hvmctx.o
>>  	$(CC) $(LDFLAGS) -o $@ $< $(LDLIBS_libxenctrl) $(APPEND_LDFLAGS)
>>  
>> diff --git a/tools/misc/xen-cpuid.c b/tools/misc/xen-cpuid.c
>> new file mode 100644
>> index 0000000..e0cd6bb
>> --- /dev/null
>> +++ b/tools/misc/xen-cpuid.c
>> @@ -0,0 +1,392 @@
>> +#include <stdio.h>
>> +#include <stdlib.h>
>> +#include <err.h>
>> +#include <getopt.h>
>> +#include <string.h>
>> +
>> +#include <xenctrl.h>
>> +#include "cpuid-private.h"
>> +
>> +static uint32_t nr_features = XEN_NR_FEATURESET_ENTRIES;
>> +
>> +static const char *str_1d[32] =
> If these are to be Xen's names could they come from the common cpuid
> location such that other users of these interfaces (including Xen itself)
> can use consistent names?

Currently there are no uses of these strings in the hypervisor.  The
reason they are here is to avoid linking the stringtables.

However, I can definitely see about getting them automatically generated
from a single source of information.

>
> (and then naturally be part of the autogeneration which has been discussed)
>> + option_error:
>> +            printf("Usage: %s [ info | detail | <featureset>* ]\n", argv[0]);
> What format does <featureset> take?

: or - delimited 32bit hex strings.

Some sample outputs look like:

[root@idol ~]# xen-cpuid
nr_features: 9
                      KEY 1d       1c       e1d      e1c      Da1     
7b0      7c0      e7d      e8b     

Static sets:
Known                    
ffeffbff:fffef7ff:efdbfbff:2469bfff:0000000f:21dcffbb:00000001:00000100:00000001
Inverted                 
00000000:00000000:00000000:00000000:00000000:00002000:00000000:00000000:00000000
PV Mask                  
07c9cbf5:fef83203:e3d9cbf5:042189e1:00000007:21cc0b39:00000001:00000000:00000000
HVM Shadow Mask          
07cbfbff:fffa3223:efdbfbff:04218df5:0000000f:21dc0fbb:00000001:00000000:00000000
HVM Hap Mask             
07cbfbff:fffa3223:efdbfbff:04218df5:0000000f:21dc0fbb:00000001:00000000:00000000

Dynamic sets:
Host                     
bfebfbff:0000e43d:20100800:00000001:00000000:00002000:00000000:00000000:00000000
PV                       
07c9cbf5:80002001:20100800:00000001:00000000:00000000:00000000:00000000:00000000
HVM                      
07cbfbff:80002021:20100800:00000001:00000000:00000000:00000000:00000000:00000000
Raw                      
bfebfbff:0000e43d:20100800:00000001:00000000:00002000:00000000:00000000:00000000
[root@idol ~]# xen-cpuid
07cbfbff:80002021:20100800:00000001:00000000:00000000:00000000:00000000:00000000
Raw                      
07cbfbff:80002021:20100800:00000001:00000000:00000000:00000000:00000000:00000000
  [00] 0x00000001.edx     fpu vme de pse tsc msr pae mce cx8 apic
sysenter mtrr pge mca cmov pat pse36 clflsh acpi mmx fxsr sse sse2
  [01] 0x00000001.ecx     sse3 vmx cx16 hyper
  [02] 0x80000001.edx     syscall nx lm
  [03] 0x80000001.ecx     lahf_lm
  [04] 0x0000000d:1.eax 
  [05] 0x00000007:0.ebx 
  [06] 0x00000007:0.ecx 
  [07] 0x80000007.edx   
  [08] 0x80000008.ebx   

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 08/31] tools/stubs: Expose host featureset to userspace
  2016-01-05 16:09       ` Ian Campbell
@ 2016-01-05 16:19         ` Andrew Cooper
  2016-01-05 16:38           ` Ian Campbell
  0 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2016-01-05 16:19 UTC (permalink / raw)
  To: Ian Campbell, Xen-devel; +Cc: Wei Liu, Ian Jackson, Rob Hoes, David Scott

On 05/01/16 16:09, Ian Campbell wrote:
> On Tue, 2016-01-05 at 15:59 +0000, Andrew Cooper wrote:
>> On 05/01/16 15:36, Ian Campbell wrote:
>>> On Wed, 2015-12-16 at 21:24 +0000, Andrew Cooper wrote:
>>>> diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c
>>>> index c613545..4d7af3d 100644
>>>> --- a/tools/libxc/xc_misc.c
>>>> +++ b/tools/libxc/xc_misc.c
>>>> @@ -718,6 +718,33 @@ int xc_hvm_inject_trap(
>>>>      return rc;
>>>>  }
>>>>  
>>>> +int xc_get_featureset(xc_interface *xch, uint32_t index,
>>>> +                      uint32_t *nr_features, uint32_t *featureset)
>>> This looks like a valid binding to the hypercall iface, so once that is
>>> agreed this LGTM.
>>>
>>>> diff --git a/tools/ocaml/libs/xc/xenctrl_stubs.c
>>>> b/tools/ocaml/libs/xc/xenctrl_stubs.c
>>>> index b7de615..a47473b 100644
>>>> --- a/tools/ocaml/libs/xc/xenctrl_stubs.c
>>>> +++ b/tools/ocaml/libs/xc/xenctrl_stubs.c
>>>> @@ -1220,6 +1220,41 @@ CAMLprim value
>>>> stub_xc_domain_deassign_device(value xch, value domid, value desc
>>>>  	CAMLreturn(Val_unit);
>>>>  }
>>>>  
>>>> +CAMLprim value stub_xc_get_featureset(value xch, value idx)
>>>> +{
>>>> +	CAMLparam2(xch, idx);
>>>> +	CAMLlocal1(bitmap_val);
>>>> +
>>>> +	/* Safe, because of the global ocaml lock. */
>>>> +	static uint32_t fs_len;
>>>> +
>>>> +	if (fs_len == 0)
>>>> +	{
>>>> +		int ret = xc_get_featureset(_H(xch), 0, &fs_len,
>>>> NULL);
>>>> +
>>>> +		if (ret || (fs_len == 0))
>>>> +			failwith_xc(_H(xch));
>>>> +	}
>>> This confuses me because I had thought when reading the previous patch
>>> that
>>> the output nr_features would depend on the specific index, is that not
>>> the
>>> case? Maybe this is just a hypercall docs fix?
>> nr_features is compile-time-constant in Xen, and every featureset handed
>> back will be of that length.
> IOW if the featureset given to the hypercall is NULL then index is ignored?
> Worth documenting.

>From the previous patch,

+struct xen_sysctl_featureset {
+#define XEN_SYSCTL_featureset_host      0
+    uint32_t index;       /* IN: Which featureset to query? */
+    uint32_t nr_features; /* IN/OUT: Number of entries in/written to
+                           * 'features', or the maximum number of features if
+                           * the guest handle is NULL. */
+    XEN_GUEST_HANDLE_64(uint32) features; /* OUT: */


This is the usual documentation for this behaviour.  Is that enough?

>
>> It is expected to grow given new changes to Xen, but won't change at
>> runtime.
> And we never expect any index to need a different length to all the others?

All bitmaps returned use bits from the same numberspace, which are going
to have the same maximum potential length.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 13/31] tools/libxc: Wire a featureset through to cpuid policy logic
  2016-01-05 15:42   ` Ian Campbell
@ 2016-01-05 16:20     ` Andrew Cooper
  0 siblings, 0 replies; 123+ messages in thread
From: Andrew Cooper @ 2016-01-05 16:20 UTC (permalink / raw)
  To: Ian Campbell, Xen-devel; +Cc: Wei Liu, Ian Jackson

On 05/01/16 15:42, Ian Campbell wrote:
> On Wed, 2015-12-16 at 21:24 +0000, Andrew Cooper wrote:
>> Later changes will cause the cpuid generation logic to seed their
>> information
>> from a featureset.  This patch adds the infrastructure to specify a
>> featureset, and will obtain the appropriate default from Xen if omitted.
>>
>> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
>> ---
>> CC: Ian Campbell <Ian.Campbell@citrix.com>
>> CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
>> CC: Wei Liu <wei.liu2@citrix.com>
>> ---
>>  tools/libxc/include/xenctrl.h |  3 ++
>>  tools/libxc/xc_cpuid_x86.c    | 90
>> ++++++++++++++++++++++++++++++++++++++-----
>>  2 files changed, 84 insertions(+), 9 deletions(-)
>>
>> diff --git a/tools/libxc/include/xenctrl.h
>> b/tools/libxc/include/xenctrl.h
>> index 27e1f45..b44aec7 100644
>> --- a/tools/libxc/include/xenctrl.h
>> +++ b/tools/libxc/include/xenctrl.h
>> @@ -2211,6 +2211,9 @@ int xc_cpuid_set(xc_interface *xch,
>>                   char **config_transformed);
>>  int xc_cpuid_apply_policy(xc_interface *xch,
>>                            domid_t domid);
>> +int xc_cpuid_apply_policy_with_featureset(xc_interface *xch, domid_t domid,
>> +                                          uint32_t *featureset,
>> +                                          unsigned int nr_features);
> We should aim to eventually only have one apply policy interface here not
> two, unless there is some good reason why xc_cpuid_apply_policy() should
> remain?
>
> AIUI passing featureset==NULL is going to be semantically identical to the
> old interface, so I think we should just go with adding the new parameters
> to the existing function.

Will do.

>
>> @@ -103,6 +109,32 @@ static int get_cpuid_domain_info(xc_interface *xch, domid_t domid,
>>      info->hvm = di.hvm;
>>      info->pvh = di.pvh;
>>  
>> +    /* Get featureset information. */
>> +    rc = xc_get_featureset(xch, XEN_SYSCTL_featureset_host,
>> +                           &host_nr_features, NULL);
>> +    if ( rc )
>> +        return rc;
>> +
>> +    if ( host_nr_features < XEN_FEATURESET_7c0 )
>> +        return -EINVAL;
> Could we assert this? I mean if Xen and libxc don't agree on this then
> something went pretty wrong during the dev window.

Will do.

>
>> +
>> +    info->featureset = calloc(host_nr_features, sizeof(*info->featureset));
>> +    if ( !info->featureset )
>> +        return -ENOMEM;
>> +
>> +    info->nr_features = host_nr_features;
>> +
>> +    if ( featureset )
>> +    {
>> +        memcpy(info->featureset, featureset,
>> +               min(host_nr_features, nr_features) * sizeof(*info->featureset));
>> +
>> +        /* Check for trucated set bits. */
> "truncated"

Will fix.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 14/31] tools/libxc: Use featureset rather than guesswork
  2016-01-05 15:54   ` Ian Campbell
@ 2016-01-05 16:22     ` Andrew Cooper
  0 siblings, 0 replies; 123+ messages in thread
From: Andrew Cooper @ 2016-01-05 16:22 UTC (permalink / raw)
  To: Ian Campbell, Xen-devel; +Cc: Wei Liu, Ian Jackson

On 05/01/16 15:54, Ian Campbell wrote:
> On Wed, 2015-12-16 at 21:24 +0000, Andrew Cooper wrote:
>> It is conceptually wrong to base a VM's featureset on the features
>> visible to
>> the toolstack which happens to construct it.
>>
>> Instead, the featureset used is either an explicit one passed by the
>> toolstack, or the default which Xen believes it can give to the guest.
>>
>> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
>> ---
>> CC: Ian Campbell <Ian.Campbell@citrix.com>
>> CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
>> CC: Wei Liu <wei.liu2@citrix.com>
>> ---
>>  tools/libxc/xc_cpuid_x86.c | 229 +++++++++++++------------------------
>> --------
>>  1 file changed, 64 insertions(+), 165 deletions(-)
>>
>> diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
>> index 8bd3126..3f39306 100644
>> --- a/tools/libxc/xc_cpuid_x86.c
>> +++ b/tools/libxc/xc_cpuid_x86.c
>> @@ -24,6 +24,7 @@
>>  #include "xc_private.h"
>>  #include <xen/arch-x86/featureset.h>
>>  #include <xen/hvm/params.h>
>> +#include <xen/sysctl.h>
>>  
>>  #define bitmaskof(idx)      (1u << ((idx) & 31))
>>  #define clear_bit(idx, dst) ((dst) &= ~bitmaskof(idx))
>> @@ -211,37 +212,19 @@ static void amd_xc_cpuid_policy(xc_interface *xch,
>>              regs[0] = DEF_MAX_AMDEXT;
>>          break;
>>  
>> -    case 0x80000001: {
>> +    case 0x80000001:
>>          if ( !info->pae )
>>              clear_bit(X86_FEATURE_PAE, regs[3]);
> This (and the others which actually change in this patch) are correct
> because the locally defined clear_bit (contrary to what one might usually
> expect) includes masking off the lower bits to get the offset in the given
> word, is that right?
>
> That confused me a lot until I spotted the clear_bit in the context above.
> What do you think about renaming it to clear_feature, or something else
> without the false expectation? Just thought I'd mention it having scratched
> my head for a bit ;-), feel free to say no.

A later patch renames them so I can include the real set/test/clear_bit
from xc_bitops.h

The problem is that, until this patch, there would be a massive delta
(which is destined for /dev/null) if I proactively renamed them.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 12/31] tools: Utility for dealing with featuresets
  2016-01-05 16:14     ` Andrew Cooper
@ 2016-01-05 16:34       ` Ian Campbell
  2016-01-05 17:13         ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Ian Campbell @ 2016-01-05 16:34 UTC (permalink / raw)
  To: Andrew Cooper, Xen-devel; +Cc: Wei Liu, Ian Jackson

On Tue, 2016-01-05 at 16:14 +0000, Andrew Cooper wrote:
> On 05/01/16 15:17, Ian Campbell wrote:
> > On Wed, 2015-12-16 at 21:24 +0000, Andrew Cooper wrote:
> > > It is able to reports the current featuresets; both the static masks
> > > and
> > > dynamic featuresets from Xen, or to decode an arbitrary featureset
> > > into
> > > `/proc/cpuinfo` style strings.
> > More than adding a utility does this not also arrange for a whole bunch
> > of
> > new functionality to be compiled into libxc? That's worth mentioning
> > here.
> 
> It is almost all just data.  Only a single (trivial) function at
> present.  But yes - it is worth mentioning.
> 
> > 
> > And doesn't it do so in a non-library namespaced way (e.g.
> > with calculate_featuresets() and decode_featureset() being exposed by
> > the
> > library)?
> 
> calculate_featuresets() is hypervisor-only code and not included by this
> change, and decode_featureset() is a local function to the utility.

Ah, I obviously just got confused.

What are the symbols exported by cpuid.o in a tools build then?

> > Granted there's lots of that sort of thing already, but should we
> > really be
> > making it worse?
> > 
> > libelf avoids this by namespacing itself as a quasi-standalone library
> > in
> > both the tools and hypervisor contexts.
> 
> Nothing from the shared .c files is expected to be exposed in the API. 
> The guts of xc_cpuid_policy() end up using it, but that is an
> implementation detail.

Ah, so is the presence of the vpath stuff in libxc here spurious then?
Since the utility you are adding doesn't actually use anything which it
provides?

That would explain my confusion. (and makes the namespacing moot I think)


> > (and then naturally be part of the autogeneration which has been
> > discussed)
> > > + option_error:
> > > +            printf("Usage: %s [ info | detail | <featureset>* ]\n",
> > > argv[0]);
> > What format does <featureset> take?
> 
> : or - delimited 32bit hex strings.
> 
> Some sample outputs look like:

Thanks, so one could call

xen-cpuid ffeffbff:fffef7ff:efdbfbff:2469bfff:0000000f:21dcffbb:00000001:00000100:00000001

and expect output like:
[...]
>   [00] 0x00000001.edx     fpu vme de pse tsc msr pae mce cx8 apic
> sysenter mtrr pge mca cmov pat pse36 clflsh acpi mmx fxsr sse sse2
>   [01] 0x00000001.ecx     sse3 vmx cx16 hyper
>   [02] 0x80000001.edx     syscall nx lm
>   [03] 0x80000001.ecx     lahf_lm
>   [04] 0x0000000d:1.eax 
>   [05] 0x00000007:0.ebx 
>   [06] 0x00000007:0.ecx 
>   [07] 0x80000007.edx   
>   [08] 0x80000008.ebx   

(except not w/space mangled by my MUA)?

If one was only interested in an 0x00000001.edx value one could say

xen-cpuid ffeffbff

But what if one wants only e.g. 0x80000001.ecx? Can you say :::2469bfff or
is it just not possible?

I don't think this tools warrants full docs or a manpage or whatever, but
if you were to put the usage into a function then it could be more easily
multiline and perhaps include a bit more info, plus then my terribly minor
gripe about the use of goto which I didn't feel was worth mentioning would
go away ;-)

Ian.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 08/31] tools/stubs: Expose host featureset to userspace
  2016-01-05 16:19         ` Andrew Cooper
@ 2016-01-05 16:38           ` Ian Campbell
  0 siblings, 0 replies; 123+ messages in thread
From: Ian Campbell @ 2016-01-05 16:38 UTC (permalink / raw)
  To: Andrew Cooper, Xen-devel; +Cc: Wei Liu, Ian Jackson, Rob Hoes, David Scott

On Tue, 2016-01-05 at 16:19 +0000, Andrew Cooper wrote:
> On 05/01/16 16:09, Ian Campbell wrote:
> > On Tue, 2016-01-05 at 15:59 +0000, Andrew Cooper wrote:
> > > On 05/01/16 15:36, Ian Campbell wrote:
> > > > On Wed, 2015-12-16 at 21:24 +0000, Andrew Cooper wrote:
> > > > > diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c
> > > > > index c613545..4d7af3d 100644
> > > > > --- a/tools/libxc/xc_misc.c
> > > > > +++ b/tools/libxc/xc_misc.c
> > > > > @@ -718,6 +718,33 @@ int xc_hvm_inject_trap(
> > > > >      return rc;
> > > > >  }
> > > > >  
> > > > > +int xc_get_featureset(xc_interface *xch, uint32_t index,
> > > > > +                      uint32_t *nr_features, uint32_t
> > > > > *featureset)
> > > > This looks like a valid binding to the hypercall iface, so once
> > > > that is
> > > > agreed this LGTM.
> > > > 
> > > > > diff --git a/tools/ocaml/libs/xc/xenctrl_stubs.c
> > > > > b/tools/ocaml/libs/xc/xenctrl_stubs.c
> > > > > index b7de615..a47473b 100644
> > > > > --- a/tools/ocaml/libs/xc/xenctrl_stubs.c
> > > > > +++ b/tools/ocaml/libs/xc/xenctrl_stubs.c
> > > > > @@ -1220,6 +1220,41 @@ CAMLprim value
> > > > > stub_xc_domain_deassign_device(value xch, value domid, value desc
> > > > >  	CAMLreturn(Val_unit);
> > > > >  }
> > > > >  
> > > > > +CAMLprim value stub_xc_get_featureset(value xch, value idx)
> > > > > +{
> > > > > +	CAMLparam2(xch, idx);
> > > > > +	CAMLlocal1(bitmap_val);
> > > > > +
> > > > > +	/* Safe, because of the global ocaml lock. */
> > > > > +	static uint32_t fs_len;
> > > > > +
> > > > > +	if (fs_len == 0)
> > > > > +	{
> > > > > +		int ret = xc_get_featureset(_H(xch), 0, &fs_len,
> > > > > NULL);
> > > > > +
> > > > > +		if (ret || (fs_len == 0))
> > > > > +			failwith_xc(_H(xch));
> > > > > +	}
> > > > This confuses me because I had thought when reading the previous
> > > > patch
> > > > that
> > > > the output nr_features would depend on the specific index, is that
> > > > not
> > > > the
> > > > case? Maybe this is just a hypercall docs fix?
> > > nr_features is compile-time-constant in Xen, and every featureset
> > > handed
> > > back will be of that length.
> > IOW if the featureset given to the hypercall is NULL then index is
> > ignored?
> > Worth documenting.
> 
> From the previous patch,
> 
> +struct xen_sysctl_featureset {
> +#define XEN_SYSCTL_featureset_host      0
> +    uint32_t index;       /* IN: Which featureset to query? */
> +    uint32_t nr_features; /* IN/OUT: Number of entries in/written to
> +                           * 'features', or the maximum number of features if
> +                           * the guest handle is NULL. */
> +    XEN_GUEST_HANDLE_64(uint32) features; /* OUT: */
> 
> 
> This is the usual documentation for this behaviour.  Is that enough?

It's not clear from this that the returned nr_features is independent of
the index (i..e a caller might infer they need to call it again and again
for each index).

I'm not sure if that is true of other similar hypercall's implementation or
documentation though.


> > 
> > > It is expected to grow given new changes to Xen, but won't change at
> > > runtime.
> > And we never expect any index to need a different length to all the
> > others?
> 
> All bitmaps returned use bits from the same numberspace, which are going
> to have the same maximum potential length.

Good, thanks.

Ian.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 15/31] x86: Generate deep dependencies of x86 features
  2016-01-05 16:03   ` Ian Campbell
@ 2016-01-05 16:42     ` Andrew Cooper
  2016-01-05 16:54       ` Ian Campbell
  0 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2016-01-05 16:42 UTC (permalink / raw)
  To: Ian Campbell, Xen-devel; +Cc: Wei Liu, Ian Jackson, Jan Beulich

On 05/01/16 16:03, Ian Campbell wrote:
> On Wed, 2015-12-16 at 21:24 +0000, Andrew Cooper wrote:
>> Some features depend on other features.  Working out and maintaining the exact
>> dependency tree is complicated, so it is expressed in script form instead.
>>
>> `gen-feature-deps.py` parses 'xen/include/public/arch-x86/featureset.h' (To
>> obtain some literal names conforming to the API), contains some single-step
>> dependency information, performs some number crunching, and writes autogen.c
>> to make the results of the number crunching available.
> In libxl we prepend a _ to autogenerated file names, may as well do the
> same here I guess.
>
>> In this case, it writes out deep dependency infomarion, to allow featureset
> "information"
>> code to find all eventual features cleared in a dependency chain.
>>
>> To be able to compile for userspace, libxc's bitmap macros are made more
>> generic (to match Xen's), and accept a void * instead of unsigned long *.
> Can we do this in a separate patch please.

Will do (for all points)

>
> IIRC void * arithmetic is a gcc (and presumably clang) extension, which we
> can specify for Xen itself, but I'm not sure about libxc (cf: recent
> discussions about building stuff for Windows).

It isn't void* arithmetic.  Simply taking a void * to facilitate
different underlying types for a bitmap.

>
> What actually breaks with the existing definitions?

Xen uses unsigned int[] for bitmaps, while libxc uses unsigned long[]. 
The compiler objects to the mix of pointers to different sized.

For a bitmap however it really doesn't matter.  At the end of the
pointer is a contiguous block of bits.

>
>> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
>> ---
>> CC: Jan Beulich <JBeulich@suse.com>
>> CC: Ian Campbell <Ian.Campbell@citrix.com>
>> CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
>> CC: Wei Liu <wei.liu2@citrix.com>
>>
>> TODO: The generation of autogen.c now means that libxc needs to be compiled
>> after the hypervisor, as the vpath doesn't convey the generation information.
>> I need to find a way to fix this.
> I'd be inclined to do the autogeneration twice with the output being
> outside the shared directory or gaining a (tools|xen)_ prefix.
>
> It's a bit wasteful to do it twice but anything else would add an
> undesirable linkage between tools and hypervisor build I think. I'm certain
> we don't want to commit the generated files.

I will see how much of this I can get into the automatically generated
part.  The problem is that there is a header file and secondary .c file
which are not automatically generated, but needed in both places.  I
definitely do not want to duplicate those.

>
>> diff --git a/xen/arch/x86/cpuid/cpuid-private.h
>> b/xen/arch/x86/cpuid/cpuid-private.h
>> index 1c92ee4..438f5d2 100644
>> --- a/xen/arch/x86/cpuid/cpuid-private.h
>> +++ b/xen/arch/x86/cpuid/cpuid-private.h
>> @@ -64,6 +64,24 @@ extern const uint32_t
>> pv_featuremask[XEN_NR_FEATURESET_ENTRIES];
>>  extern const uint32_t hvm_shadow_featuremask[XEN_NR_FEATURESET_ENTRIES];
>>  extern const uint32_t hvm_hap_featuremask[XEN_NR_FEATURESET_ENTRIES];
>>  
>> +/* A featureset with a tag. */
>> +struct tagged_featureset
>> +{
>> +    uint32_t tag;
>> +    uint32_t fs[XEN_NR_FEATURESET_ENTRIES];
>> +};
>> +
>> +/* Sparse feature matrix identifying all features which depend on a
>> feature. */
>> +extern const struct tagged_featureset deep_deps[];
> This'll be XEN_NR_FEATURESET_ENTRIES^2 entries? How big is that getting
> OOI?

It is a sparse matrix, not an n^2 matrix.  It only has entries for
features which sit in a dependency tree, which is vastly fewer than all
known features.  Currently, it is an array of 9 entries.

>
>> diff --git a/xen/arch/x86/cpuid/gen-feature-deps.py b/xen/arch/x86/cpuid/gen-feature-deps.py
>> new file mode 100755
>> index 0000000..f0ecbba
>> --- /dev/null
>> +++ b/xen/arch/x86/cpuid/gen-feature-deps.py
>> @@ -0,0 +1,152 @@
>> +#!/usr/bin/env python
>> +import sys, os, os.path as path, re
>> +
>> +names = {}
>> +
>> +with open(path.join(os.environ["XEN_ROOT"],
>> +                    "xen/include/public/arch-x86/featureset.h")) as f:
> I'd weakly prefer all the input and output paths to come from the command
> line.
>
> I have a feeling you are planning to redo a bunch of this (or if not then
> Jan was requesting something more structured which may or may not cause big
> changes here), so I'll leave the actual review for now.

Yeah - there have been a number of suggestions, so v2 is going to look
very different.

>
>> +
>> +        # Expected duplicate symbols.  Discard
>> +        if name in ('3DNOW_ALT', ):
>> +            continue
> OOI how does this arise?

Bug in older AMD processors.  See the first and final hunks of c/s d8ba3a9

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 15/31] x86: Generate deep dependencies of x86 features
  2016-01-05 16:42     ` Andrew Cooper
@ 2016-01-05 16:54       ` Ian Campbell
  2016-01-05 17:09         ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Ian Campbell @ 2016-01-05 16:54 UTC (permalink / raw)
  To: Andrew Cooper, Xen-devel; +Cc: Wei Liu, Ian Jackson, Jan Beulich

On Tue, 2016-01-05 at 16:42 +0000, Andrew Cooper wrote:
> 
> > IIRC void * arithmetic is a gcc (and presumably clang) extension, which
> > we
> > can specify for Xen itself, but I'm not sure about libxc (cf: recent
> > discussions about building stuff for Windows).
> 
> It isn't void* arithmetic.  Simply taking a void * to facilitate
> different underlying types for a bitmap.
> 
> > 
> > What actually breaks with the existing definitions?
> 
> Xen uses unsigned int[] for bitmaps, while libxc uses unsigned long[]. 
> The compiler objects to the mix of pointers to different sized.

Did you also change Xen to void somewhere in this series, or if not why not
change libxc to use an unsigned int[] if we want them to be consistent?


> > > Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> > > ---
> > > CC: Jan Beulich <JBeulich@suse.com>
> > > CC: Ian Campbell <Ian.Campbell@citrix.com>
> > > CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
> > > CC: Wei Liu <wei.liu2@citrix.com>
> > > 
> > > TODO: The generation of autogen.c now means that libxc needs to be
> > > compiled
> > > after the hypervisor, as the vpath doesn't convey the generation
> > > information.
> > > I need to find a way to fix this.
> > I'd be inclined to do the autogeneration twice with the output being
> > outside the shared directory or gaining a (tools|xen)_ prefix.
> > 
> > It's a bit wasteful to do it twice but anything else would add an
> > undesirable linkage between tools and hypervisor build I think. I'm
> > certain
> > we don't want to commit the generated files.
> 
> I will see how much of this I can get into the automatically generated
> part.  The problem is that there is a header file and secondary .c file
> which are not automatically generated, but needed in both places.  I
> definitely do not want to duplicate those.

The secondary.c seems ok, it'll get vpathd.

The header, I suppose it depends which way the #include goes from the
generated things, at worst it'd be an #ifdef or a flag to the generator I
guess?

> > > +/* Sparse feature matrix identifying all features which depend on a
> > > feature. */
> > > +extern const struct tagged_featureset deep_deps[];
> > This'll be XEN_NR_FEATURESET_ENTRIES^2 entries? How big is that getting
> > OOI?
> 
> It is a sparse matrix, not an n^2 matrix.  It only has entries for
> features which sit in a dependency tree, which is vastly fewer than all
> known features.  Currently, it is an array of 9 entries.

I'd probably just call this a (sorted) list of dependencies, but ok then ;-
)

> > > +
> > > +        # Expected duplicate symbols.  Discard
> > > +        if name in ('3DNOW_ALT', ):
> > > +            continue
> > OOI how does this arise?
> 
> Bug in older AMD processors.  See the first and final hunks of c/s
> d8ba3a9

Lovely!

I think I'd say "Expected duplicate values" since I thought the name
3DNOW_ALT was what was duplicated, which made me wonder how it compiled...

If you dropped the appearance of being generic the comment could usefully
give a hint about BPE, afterall this should be a pretty exceptional
occurrence and another if with another comment for the next one doesn't
seem too hateful.

> 
> ~Andrew

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 15/31] x86: Generate deep dependencies of x86 features
  2016-01-05 16:54       ` Ian Campbell
@ 2016-01-05 17:09         ` Andrew Cooper
  2016-01-05 17:19           ` Ian Campbell
  0 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2016-01-05 17:09 UTC (permalink / raw)
  To: Ian Campbell, Xen-devel; +Cc: Wei Liu, Ian Jackson, Jan Beulich

On 05/01/16 16:54, Ian Campbell wrote:
> On Tue, 2016-01-05 at 16:42 +0000, Andrew Cooper wrote:
>>  
>>> IIRC void * arithmetic is a gcc (and presumably clang) extension, which
>>> we
>>> can specify for Xen itself, but I'm not sure about libxc (cf: recent
>>> discussions about building stuff for Windows).
>> It isn't void* arithmetic.  Simply taking a void * to facilitate
>> different underlying types for a bitmap.
>>
>>> What actually breaks with the existing definitions?
>> Xen uses unsigned int[] for bitmaps, while libxc uses unsigned long[]. 
>> The compiler objects to the mix of pointers to different sized.
> Did you also change Xen to void somewhere in this series, or if not why not
> change libxc to use an unsigned int[] if we want them to be consistent?

Xen already uses void *, so the code using __set_bit() can use its
preferred underlying types for bitmaps.

libxc bitmaps are unsigned long *, but the featureset abi specifies
uint32_t *.  IIRC several bits of libxc code uses deliberate typecasting
to use xc_bitops.h.  void * is definitely the correct solution all around.

>
>
>>>> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
>>>> ---
>>>> CC: Jan Beulich <JBeulich@suse.com>
>>>> CC: Ian Campbell <Ian.Campbell@citrix.com>
>>>> CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
>>>> CC: Wei Liu <wei.liu2@citrix.com>
>>>>
>>>> TODO: The generation of autogen.c now means that libxc needs to be
>>>> compiled
>>>> after the hypervisor, as the vpath doesn't convey the generation
>>>> information.
>>>> I need to find a way to fix this.
>>> I'd be inclined to do the autogeneration twice with the output being
>>> outside the shared directory or gaining a (tools|xen)_ prefix.
>>>
>>> It's a bit wasteful to do it twice but anything else would add an
>>> undesirable linkage between tools and hypervisor build I think. I'm
>>> certain
>>> we don't want to commit the generated files.
>> I will see how much of this I can get into the automatically generated
>> part.  The problem is that there is a header file and secondary .c file
>> which are not automatically generated, but needed in both places.  I
>> definitely do not want to duplicate those.
> The secondary.c seems ok, it'll get vpathd.
>
> The header, I suppose it depends which way the #include goes from the
> generated things, at worst it'd be an #ifdef or a flag to the generator I
> guess?

I will see how v2 ends up looking.

>
>>>> +/* Sparse feature matrix identifying all features which depend on a
>>>> feature. */
>>>> +extern const struct tagged_featureset deep_deps[];
>>> This'll be XEN_NR_FEATURESET_ENTRIES^2 entries? How big is that getting
>>> OOI?
>> It is a sparse matrix, not an n^2 matrix.  It only has entries for
>> features which sit in a dependency tree, which is vastly fewer than all
>> known features.  Currently, it is an array of 9 entries.
> I'd probably just call this a (sorted) list of dependencies, but ok then ;-
> )

In which case I don't think I have conveyed its meaning properly.  It
might be better understood in the context of patches 17 and 19.

>
>>>> +
>>>> +        # Expected duplicate symbols.  Discard
>>>> +        if name in ('3DNOW_ALT', ):
>>>> +            continue
>>> OOI how does this arise?
>> Bug in older AMD processors.  See the first and final hunks of c/s
>> d8ba3a9
> Lovely!
>
> I think I'd say "Expected duplicate values" since I thought the name
> 3DNOW_ALT was what was duplicated, which made me wonder how it compiled...
>
> If you dropped the appearance of being generic the comment could usefully
> give a hint about BPE, afterall this should be a pretty exceptional
> occurrence and another if with another comment for the next one doesn't
> seem too hateful.

Now I think about it, it is probably better to drop 3DNOW_ALT and just
use PBE in the AMD bugfix, beside the comment.

That way, we take a "strictly no duplicate" policy.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 12/31] tools: Utility for dealing with featuresets
  2016-01-05 16:34       ` Ian Campbell
@ 2016-01-05 17:13         ` Andrew Cooper
  2016-01-05 17:37           ` Ian Campbell
  0 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2016-01-05 17:13 UTC (permalink / raw)
  To: Ian Campbell, Xen-devel; +Cc: Wei Liu, Ian Jackson

On 05/01/16 16:34, Ian Campbell wrote:
> On Tue, 2016-01-05 at 16:14 +0000, Andrew Cooper wrote:
>> On 05/01/16 15:17, Ian Campbell wrote:
>>> On Wed, 2015-12-16 at 21:24 +0000, Andrew Cooper wrote:
>>>> It is able to reports the current featuresets; both the static masks
>>>> and
>>>> dynamic featuresets from Xen, or to decode an arbitrary featureset
>>>> into
>>>> `/proc/cpuinfo` style strings.
>>> More than adding a utility does this not also arrange for a whole bunch
>>> of
>>> new functionality to be compiled into libxc? That's worth mentioning
>>> here.
>> It is almost all just data.  Only a single (trivial) function at
>> present.  But yes - it is worth mentioning.
>>
>>> And doesn't it do so in a non-library namespaced way (e.g.
>>> with calculate_featuresets() and decode_featureset() being exposed by
>>> the
>>> library)?
>> calculate_featuresets() is hypervisor-only code and not included by this
>> change, and decode_featureset() is a local function to the utility.
> Ah, I obviously just got confused.
>
> What are the symbols exported by cpuid.o in a tools build then?

There are two cpuid.o's, which is a source of confusion.

cpuid-private.h is the declaration of the symbols which get shared
between Xen and libxc.

They are: SHARED_1d, known_features[], inverted_features[],
{pv,hvm_shadow,hvm_hap}_featuremask[], struct tagged_featureset,
deep_deps[], nr_deep_deps, deep_dep_features[] and lookup_deep_deps().

>
>>> Granted there's lots of that sort of thing already, but should we
>>> really be
>>> making it worse?
>>>
>>> libelf avoids this by namespacing itself as a quasi-standalone library
>>> in
>>> both the tools and hypervisor contexts.
>> Nothing from the shared .c files is expected to be exposed in the API. 
>> The guts of xc_cpuid_policy() end up using it, but that is an
>> implementation detail.
> Ah, so is the presence of the vpath stuff in libxc here spurious then?

No - this utility needs the generated data (specifically the static
*_featuremask[] bitmaps), so the vpath is needed.

> Since the utility you are adding doesn't actually use anything which it
> provides?
>
> That would explain my confusion. (and makes the namespacing moot I think)

The namespacing is probably not moot, sadly.

>
>
>>> (and then naturally be part of the autogeneration which has been
>>> discussed)
>>>> + option_error:
>>>> +            printf("Usage: %s [ info | detail | <featureset>* ]\n",
>>>> argv[0]);
>>> What format does <featureset> take?
>> : or - delimited 32bit hex strings.
>>
>> Some sample outputs look like:
> Thanks, so one could call
>
> xen-cpuid ffeffbff:fffef7ff:efdbfbff:2469bfff:0000000f:21dcffbb:00000001:00000100:00000001
>
> and expect output like:
> [...]
>>   [00] 0x00000001.edx     fpu vme de pse tsc msr pae mce cx8 apic
>> sysenter mtrr pge mca cmov pat pse36 clflsh acpi mmx fxsr sse sse2
>>   [01] 0x00000001.ecx     sse3 vmx cx16 hyper
>>   [02] 0x80000001.edx     syscall nx lm
>>   [03] 0x80000001.ecx     lahf_lm
>>   [04] 0x0000000d:1.eax 
>>   [05] 0x00000007:0.ebx 
>>   [06] 0x00000007:0.ecx 
>>   [07] 0x80000007.edx   
>>   [08] 0x80000008.ebx   
> (except not w/space mangled by my MUA)?
>
> If one was only interested in an 0x00000001.edx value one could say
>
> xen-cpuid ffeffbff
>
> But what if one wants only e.g. 0x80000001.ecx? Can you say :::2469bfff or
> is it just not possible?

Currently,

[root@idol ~]# xen-cpuid 4
Raw                       00000004
  [00] 0x00000001.edx     de
[root@idol ~]# xen-cpuid 0::2
Raw                       00000000
  [00] 0x00000001.edx   
[root@idol ~]# xen-cpuid 0:0:2
Raw                       00000000:00000000:00000002
  [00] 0x00000001.edx   
  [01] 0x00000001.ecx   
  [02] 0x80000001.edx     vme

But I can easily edit it to permit something like :::2469bfff

>
> I don't think this tools warrants full docs or a manpage or whatever, but
> if you were to put the usage into a function then it could be more easily
> multiline and perhaps include a bit more info, plus then my terribly minor
> gripe about the use of goto which I didn't feel was worth mentioning would
> go away ;-)

Its main use is without any parameters, at which point it dumps the
static and dynamic masks for the currently-running hypervisor.

I thought it might be nice to be able to set difference calculations,
but that got rather complicated.  It is a debug utility after all.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 15/31] x86: Generate deep dependencies of x86 features
  2016-01-05 17:09         ` Andrew Cooper
@ 2016-01-05 17:19           ` Ian Campbell
  0 siblings, 0 replies; 123+ messages in thread
From: Ian Campbell @ 2016-01-05 17:19 UTC (permalink / raw)
  To: Andrew Cooper, Xen-devel; +Cc: Wei Liu, Ian Jackson, Jan Beulich

On Tue, 2016-01-05 at 17:09 +0000, Andrew Cooper wrote:
> On 05/01/16 16:54, Ian Campbell wrote:
> > On Tue, 2016-01-05 at 16:42 +0000, Andrew Cooper wrote:
> > >  
> > > > IIRC void * arithmetic is a gcc (and presumably clang) extension,
> > > > which
> > > > we
> > > > can specify for Xen itself, but I'm not sure about libxc (cf:
> > > > recent
> > > > discussions about building stuff for Windows).
> > > It isn't void* arithmetic.  Simply taking a void * to facilitate
> > > different underlying types for a bitmap.
> > > 
> > > > What actually breaks with the existing definitions?
> > > Xen uses unsigned int[] for bitmaps, while libxc uses unsigned
> > > long[]. 
> > > The compiler objects to the mix of pointers to different sized.
> > Did you also change Xen to void somewhere in this series, or if not why
> > not
> > change libxc to use an unsigned int[] if we want them to be consistent?
> 
> Xen already uses void *, so the code using __set_bit() can use its
> preferred underlying types for bitmaps.

Oh sorry, you were talking about the actual declared variables when you
said int, not the functions which operate on them.

> libxc bitmaps are unsigned long *, but the featureset abi specifies
> uint32_t *.  IIRC several bits of libxc code uses deliberate typecasting
> to use xc_bitops.h.  void * is definitely the correct solution all
> around.

Right.
> 
> > 
> > > > > +
> > > > > +        # Expected duplicate symbols.  Discard
> > > > > +        if name in ('3DNOW_ALT', ):
> > > > > +            continue
> > > > OOI how does this arise?
> > > Bug in older AMD processors.  See the first and final hunks of c/s
> > > d8ba3a9
> > Lovely!
> > 
> > I think I'd say "Expected duplicate values" since I thought the name
> > 3DNOW_ALT was what was duplicated, which made me wonder how it
> > compiled...
> > 
> > If you dropped the appearance of being generic the comment could
> > usefully
> > give a hint about BPE, afterall this should be a pretty exceptional
> > occurrence and another if with another comment for the next one doesn't
> > seem too hateful.
> 
> Now I think about it, it is probably better to drop 3DNOW_ALT and just
> use PBE in the AMD bugfix, beside the comment.
> 
> That way, we take a "strictly no duplicate" policy.

That sounds plausible.


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 12/31] tools: Utility for dealing with featuresets
  2016-01-05 17:13         ` Andrew Cooper
@ 2016-01-05 17:37           ` Ian Campbell
  2016-01-05 18:04             ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Ian Campbell @ 2016-01-05 17:37 UTC (permalink / raw)
  To: Andrew Cooper, Xen-devel; +Cc: Wei Liu, Ian Jackson

On Tue, 2016-01-05 at 17:13 +0000, Andrew Cooper wrote:
> They are: SHARED_1d, known_features[], inverted_features[],
> {pv,hvm_shadow,hvm_hap}_featuremask[], struct tagged_featureset,
> deep_deps[], nr_deep_deps, deep_dep_features[] and lookup_deep_deps().

Which ones of these are expected to be consumed by applications/utilities
using libxc as well as shared between Xen and libxc?

You mention *_featuremask below.

> > > > Granted there's lots of that sort of thing already, but should we
> > > > really be
> > > > making it worse?
> > > > 
> > > > libelf avoids this by namespacing itself as a quasi-standalone
> > > > library
> > > > in
> > > > both the tools and hypervisor contexts.
> > > Nothing from the shared .c files is expected to be exposed in the
> > > API. 
> > > The guts of xc_cpuid_policy() end up using it, but that is an
> > > implementation detail.
> > Ah, so is the presence of the vpath stuff in libxc here spurious then?
> 
> No - this utility needs the generated data (specifically the static
> *_featuremask[] bitmaps), so the vpath is needed.

OK, so those which are used by this tool are therefore being added to the
set of exported libxenctrl symbols and are not namespaced correctly.

Also, it seems wrong for something in tools/misc to be delving into
xen/blah and including "cpuid-private.h" (or if it does then it should
build it's own cpuid.o, but I don't like that either). This is akin to the
various inclusions of x?_private.h which we are trying to remove.

If these symbols are to be consumed outside of libxc and Xen by apps
linking against libxc then they need to be prototyped in xenctrl.h, I
think, or the header needs to become public itself.

How bad does providing xc_get_*_featuremask sound? How to cleanly expose
the size of the various arrays consistently is the first annoying niggle
which I thought of.

> > Since the utility you are adding doesn't actually use anything which it
> > provides?
> > 
> > That would explain my confusion. (and makes the namespacing moot I
> > think)
> 
> The namespacing is probably not moot, sadly.

Indeed.

> (and then naturally be part of the autogeneration which has been
> > > > discussed)
> > > > > + option_error:
> > > > > +            printf("Usage: %s [ info | detail | <featureset>*
> > > > > ]\n",
> > > > > argv[0]);
> > > > What format does <featureset> take?
> > > : or - delimited 32bit hex strings.
> > > 
> > > Some sample outputs look like:
> > Thanks, so one could call
> > 
> > xen-cpuid
> > ffeffbff:fffef7ff:efdbfbff:2469bfff:0000000f:21dcffbb:00000001:00000100
> > :00000001
> > 
> > and expect output like:
> > [...]
> > >   [00] 0x00000001.edx     fpu vme de pse tsc msr pae mce cx8 apic
> > > sysenter mtrr pge mca cmov pat pse36 clflsh acpi mmx fxsr sse sse2
> > >   [01] 0x00000001.ecx     sse3 vmx cx16 hyper
> > >   [02] 0x80000001.edx     syscall nx lm
> > >   [03] 0x80000001.ecx     lahf_lm
> > >   [04] 0x0000000d:1.eax 
> > >   [05] 0x00000007:0.ebx 
> > >   [06] 0x00000007:0.ecx 
> > >   [07] 0x80000007.edx   
> > >   [08] 0x80000008.ebx   
> > (except not w/space mangled by my MUA)?
> > 
> > If one was only interested in an 0x00000001.edx value one could say
> > 
> > xen-cpuid ffeffbff
> > 
> > But what if one wants only e.g. 0x80000001.ecx? Can you say :::2469bfff
> > or
> > is it just not possible?
> 
> Currently,
> 
> [root@idol ~]# xen-cpuid 4
> Raw                       00000004
>   [00] 0x00000001.edx     de
> [root@idol ~]# xen-cpuid 0::2
> Raw                       00000000
>   [00] 0x00000001.edx   

> [root@idol ~]# xen-cpuid 0:0:2
> Raw                       00000000:00000000:00000002
>   [00] 0x00000001.edx   
>   [01] 0x00000001.ecx   
>   [02] 0x80000001.edx     vme
> 
> But I can easily edit it to permit something like :::2469bfff

Seems nice to me, but really I don't mind as long it is clear how one
drives it.

> > I don't think this tools warrants full docs or a manpage or whatever,
> > but
> > if you were to put the usage into a function then it could be more
> > easily
> > multiline and perhaps include a bit more info, plus then my terribly
> > minor
> > gripe about the use of goto which I didn't feel was worth mentioning
> > would
> > go away ;-)
> 
> Its main use is without any parameters, at which point it dumps the
> static and dynamic masks for the currently-running hypervisor.

Sure, but it needs to be possible to figure out how to drive the non-main
uses too, which it currently isn't.

> I thought it might be nice to be able to set difference calculations,
> but that got rather complicated.  It is a debug utility after all.

Ian.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 12/31] tools: Utility for dealing with featuresets
  2016-01-05 17:37           ` Ian Campbell
@ 2016-01-05 18:04             ` Andrew Cooper
  2016-01-06 10:38               ` Ian Campbell
  0 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2016-01-05 18:04 UTC (permalink / raw)
  To: Ian Campbell, Xen-devel; +Cc: Wei Liu, Ian Jackson

On 05/01/16 17:37, Ian Campbell wrote:
> On Tue, 2016-01-05 at 17:13 +0000, Andrew Cooper wrote:
>> They are: SHARED_1d, known_features[], inverted_features[],
>> {pv,hvm_shadow,hvm_hap}_featuremask[], struct tagged_featureset,
>> deep_deps[], nr_deep_deps, deep_dep_features[] and lookup_deep_deps().
> Which ones of these are expected to be consumed by applications/utilities
> using libxc as well as shared between Xen and libxc?

libxc uses all the deep_deps, but only as an internal implementation
detail of xc_cpuid_apply_policy()

I do not expect anything from cpuid-private.h to be exposed in the libxc
API, although by the looks of it, the symbols are actually present in
libxenctrl.so

>
> You mention *_featuremask below.
>
>>>>> Granted there's lots of that sort of thing already, but should we
>>>>> really be
>>>>> making it worse?
>>>>>
>>>>> libelf avoids this by namespacing itself as a quasi-standalone
>>>>> library
>>>>> in
>>>>> both the tools and hypervisor contexts.
>>>> Nothing from the shared .c files is expected to be exposed in the
>>>> API. 
>>>> The guts of xc_cpuid_policy() end up using it, but that is an
>>>> implementation detail.
>>> Ah, so is the presence of the vpath stuff in libxc here spurious then?
>> No - this utility needs the generated data (specifically the static
>> *_featuremask[] bitmaps), so the vpath is needed.
> OK, so those which are used by this tool are therefore being added to the
> set of exported libxenctrl symbols and are not namespaced correctly.
>
> Also, it seems wrong for something in tools/misc to be delving into
> xen/blah and including "cpuid-private.h" (or if it does then it should
> build it's own cpuid.o, but I don't like that either). This is akin to the
> various inclusions of x?_private.h which we are trying to remove.
>
> If these symbols are to be consumed outside of libxc and Xen by apps
> linking against libxc then they need to be prototyped in xenctrl.h, I
> think, or the header needs to become public itself.
>
> How bad does providing xc_get_*_featuremask sound? How to cleanly expose
> the size of the various arrays consistently is the first annoying niggle
> which I thought of.

I will see whether I can make something like this happen.  It certainly
wouldn't be hard to get enough exposed in the libxc api for the debug
utility to be happy.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 01/31] xen/public: Export featureset information in the public API
  2015-12-23 11:26             ` Andrew Cooper
@ 2016-01-06  7:43               ` Jan Beulich
  0 siblings, 0 replies; 123+ messages in thread
From: Jan Beulich @ 2016-01-06  7:43 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: tim, Ian.Campbell, xen-devel

>>> On 23.12.15 at 12:26, <andrew.cooper3@citrix.com> wrote:
> On 23/12/2015 10:24, Jan Beulich wrote:
>>>>> Andrew Cooper <andrew.cooper3@citrix.com> 12/23/15 11:05 AM >>>
>>> On 22/12/2015 16:59, Jan Beulich wrote:
>>>>>>> On 22.12.15 at 17:42, <andrew.cooper3@citrix.com> wrote:
>>>>> On 22/12/15 16:28, Jan Beulich wrote:
>>>>>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>>>>>> +#define XEN_FEATURESET_1d     0 /* 0x00000001.edx      */
>>>>>>> +#define XEN_FEATURESET_1c     1 /* 0x00000001.ecx      */
>>>>>>> +#define XEN_FEATURESET_e1d    2 /* 0x80000001.edx      */
>>>>>>> +#define XEN_FEATURESET_e1c    3 /* 0x80000001.ecx      */
>>>>>>> +#define XEN_FEATURESET_Da1    4 /* 0x0000000d:1.eax    */
>>>>>>> +#define XEN_FEATURESET_7b0    5 /* 0x00000007:0.ebx    */
>>>>>> This ends up being pretty cryptic.
>>>>> Perhaps at a first glance, but there are so many uses that a shorthand
>>>>> really is needed.  See especially the MSR masking patches towards the
>>>>> end of the series.
>>>> I understand that something short is needed. But as the main
>>>> identifier in the ABI?
>>> It really comes down to whom is intended to do what with a featureset.
>>>
>>> These values are derivable as functions of the feature values
>>> themselves, but that requires an assumption that the featureset bitmap
>>> mirrors hardware precisely.  Providing this (names not withstanding) as
>>> a part of the ABI is intended to provide that assurance.
>>>
>>> I fully intend higher levels of the toolstack to deal with a featureset
>>> as an arbitrary bitmap, but lower levels like libxc do need a greater
>>> level of understanding of its layout.
>> All understood. The question just is whether the main identifiers in the public
>> header should be this cryptic, or whether consumers should instead introduce
>> shortcuts of their liking (even more so that, just like noted elsewhere, these
>> identifiers also lack "CPU" and perhaps "x86" in their names - in the end
>> feature leveling isn't something that's needed on x86 only).
> 
> For now, I can move them along with XEN_NR_FEATURESET_ENTRIES, because
> the only bits of libxc which need them are the bits which are already
> using the shared library.
> 
> 
> The slight conceptual issue I am concerned about is how this will fit in
> with extended work to fix the rest of cpuid handling in Xen.
> 
> Other quantities, such as max_leaf and max_phys_addr need levelling
> across hosts.  At the moment, all of this information is derived from
> dom0's view and is not kept consistent across migrate.  (Surprisingly,
> windows notices this, doesn't crash, and decides to install a new CPU
> driver.)
> 
> Long term, the toolstack needs to level a complete idea of the cpuid
> policy for the guest, and the featureset is just one part of this. 
> However, I am expecting that the featureset on its own will still be a
> useful entity, which is why I progressed down this route.

I have to admit that I don't see how all this relates to the naming issue:
I don't mind the constants being publicly advertised (and in fact I agree
they need to be), just that their names should imo be readable /
understandable without deciphering.

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 12/31] tools: Utility for dealing with featuresets
  2016-01-05 18:04             ` Andrew Cooper
@ 2016-01-06 10:38               ` Ian Campbell
  0 siblings, 0 replies; 123+ messages in thread
From: Ian Campbell @ 2016-01-06 10:38 UTC (permalink / raw)
  To: Andrew Cooper, Xen-devel; +Cc: Wei Liu, Ian Jackson

On Tue, 2016-01-05 at 18:04 +0000, Andrew Cooper wrote:
> On 05/01/16 17:37, Ian Campbell wrote:
> > On Tue, 2016-01-05 at 17:13 +0000, Andrew Cooper wrote:
> > > They are: SHARED_1d, known_features[], inverted_features[],
> > > {pv,hvm_shadow,hvm_hap}_featuremask[], struct tagged_featureset,
> > > deep_deps[], nr_deep_deps, deep_dep_features[] and
> > > lookup_deep_deps().
> > Which ones of these are expected to be consumed by
> > applications/utilities
> > using libxc as well as shared between Xen and libxc?
> 
> libxc uses all the deep_deps, but only as an internal implementation
> detail of xc_cpuid_apply_policy()

I'm not interested in what libxc uses internally.

I'm interested only in what things which link against libxc, which includes
you debug utility, are using directly themselves (i.e. not via a libxc
call).

> I do not expect anything from cpuid-private.h to be exposed in the libxc
> API, although by the looks of it, the symbols are actually present in
> libxenctrl.so

Yes, this is because we don't enforce technically whether symbols are
exported or not (maybe I should write a map file which only allows xc_* and
see what breaks...).

Our closest analogue to whether something is exported vs private is "are
they used outside of tools/libxc", e.g. by tools/misc or tools/libxl, and
we have been explicitly annotating in-tree users of what we consider libxc
internals by such components, see e.g. tools/misc/Makefile and elsewhere
which have comments like:

    # xen-hptool incorrectly uses libxc internals.

Around the point they arrange for CFLAGS to point into internal stuff etc.

Your new tool is either adding a public API to libxc or adding another
instance of incorrectly using libxc internals. I don't think we want to add
any more of the latter, and certainly not without the caveats we apply to
other such cases (i.e. the comment to indicate that it is doing something
naughty).

Ian.

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 12/31] tools: Utility for dealing with featuresets
  2015-12-16 21:24 ` [PATCH RFC 12/31] tools: Utility for dealing with featuresets Andrew Cooper
  2016-01-05 15:17   ` Ian Campbell
@ 2016-01-06 10:40   ` Ian Campbell
  2016-01-06 10:42     ` Ian Campbell
  1 sibling, 1 reply; 123+ messages in thread
From: Ian Campbell @ 2016-01-06 10:40 UTC (permalink / raw)
  To: Andrew Cooper, Xen-devel; +Cc: Wei Liu, Ian Jackson

On Wed, 2015-12-16 at 21:24 +0000, Andrew Cooper wrote:
> 
> +xen-cpuid.o: CFLAGS += -I$(XEN_ROOT)/xen/arch/x86/cpuid

Would it be possible to arrange for the headers we need here to be visible
in tools/include/xen instead via the links, like we do for libelf?


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 12/31] tools: Utility for dealing with featuresets
  2016-01-06 10:40   ` Ian Campbell
@ 2016-01-06 10:42     ` Ian Campbell
  0 siblings, 0 replies; 123+ messages in thread
From: Ian Campbell @ 2016-01-06 10:42 UTC (permalink / raw)
  To: Andrew Cooper, Xen-devel; +Cc: Wei Liu, Ian Jackson

On Wed, 2016-01-06 at 10:40 +0000, Ian Campbell wrote:
> On Wed, 2015-12-16 at 21:24 +0000, Andrew Cooper wrote:
> >  
> > +xen-cpuid.o: CFLAGS += -I$(XEN_ROOT)/xen/arch/x86/cpuid
> 
> Would it be possible to arrange for the headers we need here to be visible
> in tools/include/xen instead via the links, like we do for libelf?

... assuming this is still necessary once the mechanism for exporting this
data to applications via libxc is fixed, which now I think about it it
probably won't be.

Ian.


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 18/31] xen/x86: Improve disabling of features which have dependencies
  2015-12-16 21:24 ` [PATCH RFC 18/31] xen/x86: Improve disabling of features which have dependencies Andrew Cooper
@ 2016-01-21 16:48   ` Jan Beulich
  0 siblings, 0 replies; 123+ messages in thread
From: Jan Beulich @ 2016-01-21 16:48 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
> --- a/xen/arch/x86/xstate.c
> +++ b/xen/arch/x86/xstate.c
> @@ -278,11 +278,16 @@ unsigned int xstate_ctxt_size(u64 xcr0)
>  /* Collect the information of processor's extended state */
>  void xstate_init(struct cpuinfo_x86 *c)
>  {
> +    static bool_t __initdata use_xsave = 1;
> +
>      bool_t bsp = c == &boot_cpu_data;
>      u32 eax, ebx, ecx, edx;
>      u64 feature_mask;
>  
> -    if ( boot_cpu_data.cpuid_level < XSTATE_CPUID )
> +    boolean_param("xsave", use_xsave);

Please make this sit next to the related variable. With that
Reviewed-by: Jan Beulich <jbeulich@suse.com>

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 20/31] x86: Improvements to in-hypervisor cpuid sanity checks
  2015-12-16 21:24 ` [PATCH RFC 20/31] x86: Improvements to in-hypervisor cpuid sanity checks Andrew Cooper
@ 2016-01-21 17:02   ` Jan Beulich
  2016-01-21 17:21     ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Jan Beulich @ 2016-01-21 17:02 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
> @@ -864,69 +865,27 @@ void pv_cpuid(struct cpu_user_regs *regs)
>  
>      cpuid_count(a, c, &a, &b, &c, &d);
>  
> -    if ( (regs->eax & 0x7fffffff) == 0x00000001 )
> -    {
> -        /* Modify Feature Information. */
> -        if ( !cpu_has_apic )
> -            __clear_bit(X86_FEATURE_APIC, &d);
> -
> -        if ( !is_pvh_domain(currd) )
> -        {
> -            __clear_bit(X86_FEATURE_PSE, &d);
> -            __clear_bit(X86_FEATURE_PGE, &d);
> -            __clear_bit(X86_FEATURE_PSE36, &d);
> -            __clear_bit(X86_FEATURE_VME, &d);
> -        }
> -    }

This I understand goes away because pv_featureset[] never has
those set?

>      case 0x80000001:
> -        /* Modify Feature Information. */
> -        if ( is_pv_32bit_domain(currd) )
> -        {
> -            __clear_bit(X86_FEATURE_LM % 32, &d);
> -            __clear_bit(X86_FEATURE_LAHF_LM % 32, &c);
> -        }
> -        if ( is_pv_32bit_domain(currd) &&
> -             boot_cpu_data.x86_vendor != X86_VENDOR_AMD )
> -            __clear_bit(X86_FEATURE_SYSCALL % 32, &d);

But what about these 32-bit specific removals?

Overall this of course makes things quite a bit more readable.

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 21/31] x86/domctl: Break out logic to update domain state from cpuid information
  2015-12-16 21:24 ` [PATCH RFC 21/31] x86/domctl: Break out logic to update domain state from cpuid information Andrew Cooper
@ 2016-01-21 17:05   ` Jan Beulich
  2016-01-21 17:08     ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Jan Beulich @ 2016-01-21 17:05 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
> Later changes will add to this logic.
> 
> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>

Reviewed-by: Jan Beulich <jbeulich@suse.com>

And actually looks like this is pretty independent of the earlier patches,
and hence could go in right away?

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 21/31] x86/domctl: Break out logic to update domain state from cpuid information
  2016-01-21 17:05   ` Jan Beulich
@ 2016-01-21 17:08     ` Andrew Cooper
  0 siblings, 0 replies; 123+ messages in thread
From: Andrew Cooper @ 2016-01-21 17:08 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 21/01/16 17:05, Jan Beulich wrote:
>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>> Later changes will add to this logic.
>>
>> Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
> Reviewed-by: Jan Beulich <jbeulich@suse.com>
>
> And actually looks like this is pretty independent of the earlier patches,
> and hence could go in right away?

It certainly can.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 22/31] x86/cpu: Move set_cpumask() calls into c_early_init()
  2015-12-16 21:24 ` [PATCH RFC 22/31] x86/cpu: Move set_cpumask() calls into c_early_init() Andrew Cooper
@ 2016-01-21 17:08   ` Jan Beulich
  0 siblings, 0 replies; 123+ messages in thread
From: Jan Beulich @ 2016-01-21 17:08 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
> Before c/s 44e24f8567 "x86: don't call generic_identify() redundantly", the
> commandline-provided masks would take effect in Xen's view of the features.
> 
> As the masks got applied after the query for features, the redundant call to
> generic_identify() would clobber the wrong feature information with the new,
> correct information.

I don't think "wrong" is appropriate here, since ...

> Move the set_cpumask() calls into c_early_init() so their effects take place
> before the main query for features in generic_identify().
> 
> The cpuid_mask_* command line parameters now correctly limit the entire
> system,

... I consider this wrong (both Xen and Dom0 can benefit from using
features an admin may want to mask for migration purposes), the
more ...

> although the subsequent changes will replace the need to use these
> parameters for heterogeneous levelling purposes.

... that you then make clear this won't be needed anymore.

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 20/31] x86: Improvements to in-hypervisor cpuid sanity checks
  2016-01-21 17:02   ` Jan Beulich
@ 2016-01-21 17:21     ` Andrew Cooper
  2016-01-21 18:15       ` Andrew Cooper
  2016-01-22  7:45       ` Jan Beulich
  0 siblings, 2 replies; 123+ messages in thread
From: Andrew Cooper @ 2016-01-21 17:21 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 21/01/16 17:02, Jan Beulich wrote:
>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>> @@ -864,69 +865,27 @@ void pv_cpuid(struct cpu_user_regs *regs)
>>  
>>      cpuid_count(a, c, &a, &b, &c, &d);
>>  
>> -    if ( (regs->eax & 0x7fffffff) == 0x00000001 )
>> -    {
>> -        /* Modify Feature Information. */
>> -        if ( !cpu_has_apic )
>> -            __clear_bit(X86_FEATURE_APIC, &d);
>> -
>> -        if ( !is_pvh_domain(currd) )
>> -        {
>> -            __clear_bit(X86_FEATURE_PSE, &d);
>> -            __clear_bit(X86_FEATURE_PGE, &d);
>> -            __clear_bit(X86_FEATURE_PSE36, &d);
>> -            __clear_bit(X86_FEATURE_VME, &d);
>> -        }
>> -    }
> This I understand goes away because pv_featureset[] never has
> those set?
>
>>      case 0x80000001:
>> -        /* Modify Feature Information. */
>> -        if ( is_pv_32bit_domain(currd) )
>> -        {
>> -            __clear_bit(X86_FEATURE_LM % 32, &d);
>> -            __clear_bit(X86_FEATURE_LAHF_LM % 32, &c);
>> -        }
>> -        if ( is_pv_32bit_domain(currd) &&
>> -             boot_cpu_data.x86_vendor != X86_VENDOR_AMD )
>> -            __clear_bit(X86_FEATURE_SYSCALL % 32, &d);
> But what about these 32-bit specific removals?

LM, from the deep feature dependency removal in libxc, when it is known
that the domain is 32bit.

For SYSCALL, as far as I can tell, the logic is wrong.  32bit compat
mode code on Intel can use SYSCALL, as Xen is running in Long mode. 
(This is opposite to the AMD case where 32bit compat code cannot use
SYSENTER, because Xen is in Long mode.)

> Overall this of course makes things quite a bit more readable.

And there is more to come.

By the time my cpuid phase 2 plans are complete, all validitiy checks
will be done at the set_cpuid_policy hypercall boundary, meaning that
all these time-of-use checks can be dropped.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 23/31] xen/x86: Export cpuid levelling capabilities via SYSCTL
  2015-12-16 21:24 ` [PATCH RFC 23/31] xen/x86: Export cpuid levelling capabilities via SYSCTL Andrew Cooper
@ 2016-01-21 17:23   ` Jan Beulich
  0 siblings, 0 replies; 123+ messages in thread
From: Jan Beulich @ 2016-01-21 17:23 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Tim Deegan, Ian Campbell, Xen-devel

>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
> --- a/xen/arch/x86/cpu/common.c
> +++ b/xen/arch/x86/cpu/common.c
> @@ -32,6 +32,9 @@ integer_param("cpuid_mask_ext_ecx", opt_cpuid_mask_ext_ecx);
>  unsigned int __devinitdata opt_cpuid_mask_ext_edx = ~0u;
>  integer_param("cpuid_mask_ext_edx", opt_cpuid_mask_ext_edx);
>  
> +unsigned int __initdata expected_levelling_cap;

Unused variable.

> +unsigned int __read_mostly levelling_caps;

Never written to variable.

> +/*
> + * XEN_SYSCTL_get_levelling_caps (x86 specific)
> + *
> + * Return hardware capabilities concerning masking or faulting of the cpuid
> + * instruction for PV guests.
> + */
> +struct xen_sysctl_levelling_caps {
> +/*
> + * Featureset array index encoding:
> + * - (possibly) 'e' Extended
> + * - leaf, uppercase hex
> + * - register, lowercase
> + * - (possibly) subleaf
> + */
> +#define XEN_SYSCTL_LEVELCAP_faulting (1ul <<  0) /* CPUID faulting    */
> +#define XEN_SYSCTL_LEVELCAP_1c       (1ul <<  1) /* 0x00000001.ecx    */
> +#define XEN_SYSCTL_LEVELCAP_1d       (1ul <<  2) /* 0x00000001.edx    */
> +#define XEN_SYSCTL_LEVELCAP_e1c      (1ul <<  3) /* 0x80000001.ecx    */
> +#define XEN_SYSCTL_LEVELCAP_e1d      (1ul <<  4) /* 0x80000001.edx    */
> +#define XEN_SYSCTL_LEVELCAP_Da1      (1ul <<  5) /* 0x0000000D:1.eax  */
> +#define XEN_SYSCTL_LEVELCAP_6c       (1ul <<  6) /* 0x00000006.ecx    */
> +#define XEN_SYSCTL_LEVELCAP_7a0      (1ul <<  7) /* 0x00000007:0.eax  */
> +#define XEN_SYSCTL_LEVELCAP_7b0      (1ul <<  8) /* 0x00000007:0.ebx  */

Similar comment apply to the naming here as I had given for the
feature sysctl.

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 20/31] x86: Improvements to in-hypervisor cpuid sanity checks
  2016-01-21 17:21     ` Andrew Cooper
@ 2016-01-21 18:15       ` Andrew Cooper
  2016-01-22  7:47         ` Jan Beulich
  2016-01-22  7:45       ` Jan Beulich
  1 sibling, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2016-01-21 18:15 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 21/01/16 17:21, Andrew Cooper wrote:
> On 21/01/16 17:02, Jan Beulich wrote:
>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>> @@ -864,69 +865,27 @@ void pv_cpuid(struct cpu_user_regs *regs)
>>>  
>>>      cpuid_count(a, c, &a, &b, &c, &d);
>>>  
>>> -    if ( (regs->eax & 0x7fffffff) == 0x00000001 )
>>> -    {
>>> -        /* Modify Feature Information. */
>>> -        if ( !cpu_has_apic )
>>> -            __clear_bit(X86_FEATURE_APIC, &d);
>>> -
>>> -        if ( !is_pvh_domain(currd) )
>>> -        {
>>> -            __clear_bit(X86_FEATURE_PSE, &d);
>>> -            __clear_bit(X86_FEATURE_PGE, &d);
>>> -            __clear_bit(X86_FEATURE_PSE36, &d);
>>> -            __clear_bit(X86_FEATURE_VME, &d);
>>> -        }
>>> -    }
>> This I understand goes away because pv_featureset[] never has
>> those set?
>>
>>>      case 0x80000001:
>>> -        /* Modify Feature Information. */
>>> -        if ( is_pv_32bit_domain(currd) )
>>> -        {
>>> -            __clear_bit(X86_FEATURE_LM % 32, &d);
>>> -            __clear_bit(X86_FEATURE_LAHF_LM % 32, &c);
>>> -        }
>>> -        if ( is_pv_32bit_domain(currd) &&
>>> -             boot_cpu_data.x86_vendor != X86_VENDOR_AMD )
>>> -            __clear_bit(X86_FEATURE_SYSCALL % 32, &d);
>> But what about these 32-bit specific removals?
> LM, from the deep feature dependency removal in libxc, when it is known
> that the domain is 32bit.
>
> For SYSCALL, as far as I can tell, the logic is wrong.  32bit compat
> mode code on Intel can use SYSCALL, as Xen is running in Long mode. 
> (This is opposite to the AMD case where 32bit compat code cannot use
> SYSENTER, because Xen is in Long mode.)

I have just double checked.  32bit PV guests on Intel definitely can use
syscall.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 20/31] x86: Improvements to in-hypervisor cpuid sanity checks
  2016-01-21 17:21     ` Andrew Cooper
  2016-01-21 18:15       ` Andrew Cooper
@ 2016-01-22  7:45       ` Jan Beulich
  1 sibling, 0 replies; 123+ messages in thread
From: Jan Beulich @ 2016-01-22  7:45 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 21.01.16 at 18:21, <andrew.cooper3@citrix.com> wrote:
> On 21/01/16 17:02, Jan Beulich wrote:
>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>>      case 0x80000001:
>>> -        /* Modify Feature Information. */
>>> -        if ( is_pv_32bit_domain(currd) )
>>> -        {
>>> -            __clear_bit(X86_FEATURE_LM % 32, &d);
>>> -            __clear_bit(X86_FEATURE_LAHF_LM % 32, &c);
>>> -        }
>>> -        if ( is_pv_32bit_domain(currd) &&
>>> -             boot_cpu_data.x86_vendor != X86_VENDOR_AMD )
>>> -            __clear_bit(X86_FEATURE_SYSCALL % 32, &d);
>> But what about these 32-bit specific removals?
> 
> LM, from the deep feature dependency removal in libxc, when it is known
> that the domain is 32bit.
> 
> For SYSCALL, as far as I can tell, the logic is wrong.  32bit compat
> mode code on Intel can use SYSCALL, as Xen is running in Long mode. 
> (This is opposite to the AMD case where 32bit compat code cannot use
> SYSENTER, because Xen is in Long mode.)

Intel doesn't even document a CSTAR MSR.

>> Overall this of course makes things quite a bit more readable.
> 
> And there is more to come.
> 
> By the time my cpuid phase 2 plans are complete, all validitiy checks
> will be done at the set_cpuid_policy hypercall boundary, meaning that
> all these time-of-use checks can be dropped.

And arguably it should have been that way from the beginning -
re-calculating all of these every time is ineffective, even if the
overhead isn't _that_ high.

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 20/31] x86: Improvements to in-hypervisor cpuid sanity checks
  2016-01-21 18:15       ` Andrew Cooper
@ 2016-01-22  7:47         ` Jan Beulich
  0 siblings, 0 replies; 123+ messages in thread
From: Jan Beulich @ 2016-01-22  7:47 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 21.01.16 at 19:15, <andrew.cooper3@citrix.com> wrote:
> On 21/01/16 17:21, Andrew Cooper wrote:
>> On 21/01/16 17:02, Jan Beulich wrote:
>>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>>>      case 0x80000001:
>>>> -        /* Modify Feature Information. */
>>>> -        if ( is_pv_32bit_domain(currd) )
>>>> -        {
>>>> -            __clear_bit(X86_FEATURE_LM % 32, &d);
>>>> -            __clear_bit(X86_FEATURE_LAHF_LM % 32, &c);
>>>> -        }
>>>> -        if ( is_pv_32bit_domain(currd) &&
>>>> -             boot_cpu_data.x86_vendor != X86_VENDOR_AMD )
>>>> -            __clear_bit(X86_FEATURE_SYSCALL % 32, &d);
>>> But what about these 32-bit specific removals?
>> LM, from the deep feature dependency removal in libxc, when it is known
>> that the domain is 32bit.
>>
>> For SYSCALL, as far as I can tell, the logic is wrong.  32bit compat
>> mode code on Intel can use SYSCALL, as Xen is running in Long mode. 
>> (This is opposite to the AMD case where 32bit compat code cannot use
>> SYSENTER, because Xen is in Long mode.)
> 
> I have just double checked.  32bit PV guests on Intel definitely can use
> syscall.

Double checked where? As just said in the other mail, I can't find
documentation of CSTAR being implemented anywhere in SDM Vol 3.

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 25/31] xen/x86: Common infrastructure for levelling context switching
  2015-12-16 21:24 ` [PATCH RFC 25/31] xen/x86: Common infrastructure for levelling context switching Andrew Cooper
@ 2016-01-22  8:56   ` Jan Beulich
  2016-01-22 10:05     ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Jan Beulich @ 2016-01-22  8:56 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
> --- a/xen/arch/x86/cpu/common.c
> +++ b/xen/arch/x86/cpu/common.c
> @@ -35,6 +35,9 @@ integer_param("cpuid_mask_ext_edx", opt_cpuid_mask_ext_edx);
>  unsigned int __initdata expected_levelling_cap;
>  unsigned int __read_mostly levelling_caps;
>  
> +DEFINE_PER_CPU(struct cpumasks, cpumasks);
> +struct cpumasks __read_mostly cpumask_defaults;

Any reason these can't be introduced when first used? (The question
really applies to the rest of this patch too, I guess.)

> --- a/xen/include/asm-x86/processor.h
> +++ b/xen/include/asm-x86/processor.h
> @@ -585,6 +585,21 @@ int microcode_resume_cpu(unsigned int cpu);
>   */
>  extern unsigned int expected_levelling_cap, levelling_caps;
>  
> +struct cpumasks
> +{
> +    uint64_t _1cd;
> +    uint64_t e1cd;
> +    uint64_t Da1;
> +    uint64_t _6c;
> +    uint64_t _7ab0;
> +};

While I see the need for these underscore prefixes with the
current naming scheme, perhaps it would be better to make
this fully consistent with the acronym #define-s, by e.g.
prefixing the base ones with 'b'? Such full naming consistency
would allow for string concatenation in macros, should such a
possibility ever arise, no matter whether manifest constants
or structure members here are needed to be accessed.

As to the name of the structure itself - perhaps better
cpuidmasks?

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 26/31] xen/x86: Rework AMD masking MSR setup
  2015-12-16 21:24 ` [PATCH RFC 26/31] xen/x86: Rework AMD masking MSR setup Andrew Cooper
@ 2016-01-22  9:27   ` Jan Beulich
  2016-01-22 11:01     ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Jan Beulich @ 2016-01-22  9:27 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
> This patch is best reviewed as its end result rather than as a diff, as it
> rewrites almost all of the setup.

This, I think, doesn't belong in the commit message itself.

> @@ -126,126 +133,172 @@ static const struct cpuidmask *__init noinline 
> get_cpuidmask(const char *opt)
>  }
>  
>  /*
> - * Mask the features and extended features returned by CPUID.  Parameters are
> - * set from the boot line via two methods:
> - *
> - *   1) Specific processor revision string
> - *   2) User-defined masks
> - *
> - * The processor revision string parameter has precedene.
> + * Sets caps in expected_levelling_cap, probes for the specified mask MSR, and
> + * set caps in levelling_caps if it is found.  Processors prior to Fam 10h
> + * required a 32-bit password for masking MSRs.  Reads the default value into
> + * msr_val.
>   */
> -static void __devinit set_cpuidmask(const struct cpuinfo_x86 *c)
> +static void __init __probe_mask_msr(unsigned int msr, uint64_t caps,
> +                                    uint64_t *msr_val)
>  {
> -	static unsigned int feat_ecx, feat_edx;
> -	static unsigned int extfeat_ecx, extfeat_edx;
> -	static unsigned int l7s0_eax, l7s0_ebx;
> -	static unsigned int thermal_ecx;
> -	static bool_t skip_feat, skip_extfeat;
> -	static bool_t skip_l7s0_eax_ebx, skip_thermal_ecx;
> -	static enum { not_parsed, no_mask, set_mask } status;
> -	unsigned int eax, ebx, ecx, edx;
> -
> -	if (status == no_mask)
> -		return;
> +	unsigned int hi, lo;
> +
> +        expected_levelling_cap |= caps;

Mixing indentation styles.

> +
> +	if ((rdmsr_amd_safe(msr, &lo, &hi) == 0) &&
> +	    (wrmsr_amd_safe(msr, lo, hi) == 0))
> +		levelling_caps |= caps;

This logic assumes that faults are possible only because the MSR is
not there at all, not because of the actual value used. Is this a safe
assumption, the more that you don't use the "safe" variants
anymore at runtime?

> +/*
> + * Probe for the existance of the expected masking MSRs.  They might easily
> + * not be available if Xen is running virtualised.
> + */
> +static void __init noinline probe_masking_msrs(void)
> +{
> +	const struct cpuinfo_x86 *c = &boot_cpu_data;
>  
> -	ASSERT((status == not_parsed) && (c == &boot_cpu_data));
> -	status = no_mask;
> +	/*
> +	 * First, work out which masking MSRs we should have, based on
> +	 * revision and cpuid.
> +	 */
>  
>  	/* Fam11 doesn't support masking at all. */
>  	if (c->x86 == 0x11)
>  		return;
>  
> -	if (~(opt_cpuid_mask_ecx & opt_cpuid_mask_edx &
> -	      opt_cpuid_mask_ext_ecx & opt_cpuid_mask_ext_edx &
> -	      opt_cpuid_mask_l7s0_eax & opt_cpuid_mask_l7s0_ebx &
> -	      opt_cpuid_mask_thermal_ecx)) {
> -		feat_ecx = opt_cpuid_mask_ecx;
> -		feat_edx = opt_cpuid_mask_edx;
> -		extfeat_ecx = opt_cpuid_mask_ext_ecx;
> -		extfeat_edx = opt_cpuid_mask_ext_edx;
> -		l7s0_eax = opt_cpuid_mask_l7s0_eax;
> -		l7s0_ebx = opt_cpuid_mask_l7s0_ebx;
> -		thermal_ecx = opt_cpuid_mask_thermal_ecx;
> -	} else if (*opt_famrev == '\0') {
> +	__probe_mask_msr(MSR_K8_FEATURE_MASK, LCAP_1cd,
> +			 &cpumask_defaults._1cd);
> +	__probe_mask_msr(MSR_K8_EXT_FEATURE_MASK, LCAP_e1cd,
> +			 &cpumask_defaults.e1cd);
> +
> +	if (c->cpuid_level >= 7)
> +		__probe_mask_msr(MSR_AMD_L7S0_FEATURE_MASK, LCAP_7ab0,
> +				 &cpumask_defaults._7ab0);
> +
> +	if (c->x86 == 0x15 && c->cpuid_level >= 6 && cpuid_ecx(6))
> +		__probe_mask_msr(MSR_AMD_THRM_FEATURE_MASK, LCAP_6c,
> +				 &cpumask_defaults._6c);
> +
> +	/*
> +	 * Don't bother warning about a mismatch if virtualised.  These MSRs
> +	 * are not architectural and almost never virtualised.
> +	 */
> +	if ((expected_levelling_cap == levelling_caps) ||
> +	    cpu_has_hypervisor)
>  		return;
> -	} else {
> -		const struct cpuidmask *m = get_cpuidmask(opt_famrev);
> +
> +	printk(XENLOG_WARNING "Mismatch between expected (%#x"
> +	       ") and real (%#x) levelling caps: missing %#x\n",

Breaking a format string inside parentheses is certainly a little odd.
Also I don't think the "missing" part is really useful, considering that
you already print both values used in its calculation.

> +	       expected_levelling_cap, levelling_caps,
> +	       (expected_levelling_cap ^ levelling_caps) & levelling_caps);
> +	printk(XENLOG_WARNING "Fam %#x, model %#x level %#x\n",
> +	       c->x86, c->x86_model, c->cpuid_level);
> +	printk(XENLOG_WARNING
> +	       "If not running virtualised, please report a bug\n");

Well - you checked for running virtualized, so making it here when
running virtualized is already a bug (albeit not in the code here)?

> +void amd_ctxt_switch_levelling(const struct domain *nextd)
> +{
> +	struct cpumasks *these_masks = &this_cpu(cpumasks);
> +	const struct cpumasks *masks = &cpumask_defaults;
> +
> +#define LAZY(cap, msr, field)						\
> +	({								\
> +		if ( ((levelling_caps & cap) == cap) &&			\
> +		     (these_masks->field != masks->field) )		\
> +		{							\
> +			wrmsr_amd(msr, masks->field);			\
> +			these_masks->field = masks->field;		\
> +		}							\
> +	})
> +
> +	LAZY(LCAP_1cd,  MSR_K8_FEATURE_MASK,       _1cd);
> +	LAZY(LCAP_e1cd, MSR_K8_EXT_FEATURE_MASK,   e1cd);
> +	LAZY(LCAP_7ab0, MSR_AMD_L7S0_FEATURE_MASK, _7ab0);
> +	LAZY(LCAP_6c,   MSR_AMD_THRM_FEATURE_MASK, _6c);

So here we already have the first example where fully consistent
naming would allow elimination of a macro parameter.

And then, how is this supposed to work? You only restore defaults,
but never write non-default values. Namely, nextd is an unused
function parameter ...

Also I guess my comment about adding unused code needs
repeating here.

> +/*
> + * Mask the features and extended features returned by CPUID.  Parameters are
> + * set from the boot line via two methods:
> + *
> + *   1) Specific processor revision string
> + *   2) User-defined masks
> + *
> + * The processor revision string parameter has precedence.
> + */
> +static void __init noinline amd_init_levelling(void)
> +{
> +	const struct cpuidmask *m = NULL;
> +
> +	probe_masking_msrs();
> +
> +	if (*opt_famrev != '\0') {
> +		m = get_cpuidmask(opt_famrev);
>  
>  		if (!m) {
>  			printk("Invalid processor string: %s\n", opt_famrev);
> -			printk("CPUID will not be masked\n");
> -			return;
>  		}

This leaves now pointless braces around.

> -		feat_ecx = m->ecx;
> -		feat_edx = m->edx;
> -		extfeat_ecx = m->ext_ecx;
> -		extfeat_edx = m->ext_edx;
>  	}
>  
> -        /* Setting bits in the CPUID mask MSR that are not set in the
> -         * unmasked CPUID response can cause those bits to be set in the
> -         * masked response.  Avoid that by explicitly masking in software. */
> -        feat_ecx &= cpuid_ecx(0x00000001);
> -        feat_edx &= cpuid_edx(0x00000001);
> -        extfeat_ecx &= cpuid_ecx(0x80000001);
> -        extfeat_edx &= cpuid_edx(0x80000001);
> +	if ((levelling_caps & LCAP_1cd) == LCAP_1cd) {
> +		uint32_t ecx, edx, tmp;
>  
> -	status = set_mask;
> -	printk("Writing CPUID feature mask ECX:EDX -> %08Xh:%08Xh\n", 
> -	       feat_ecx, feat_edx);
> -	printk("Writing CPUID extended feature mask ECX:EDX -> %08Xh:%08Xh\n", 
> -	       extfeat_ecx, extfeat_edx);
> +		cpuid(0x00000001, &tmp, &tmp, &ecx, &edx);
>  
> -	if (c->cpuid_level >= 7)
> -		cpuid_count(7, 0, &eax, &ebx, &ecx, &edx);
> -	else
> -		ebx = eax = 0;
> -	if ((eax | ebx) && ~(l7s0_eax & l7s0_ebx)) {
> -		if (l7s0_eax > eax)
> -			l7s0_eax = eax;
> -		l7s0_ebx &= ebx;
> -		printk("Writing CPUID leaf 7 subleaf 0 feature mask EAX:EBX -> %08Xh:%08Xh\n",
> -		       l7s0_eax, l7s0_ebx);
> -	} else
> -		skip_l7s0_eax_ebx = 1;
> -
> -	/* Only Fam15 has the respective MSR. */
> -	ecx = c->x86 == 0x15 && c->cpuid_level >= 6 ? cpuid_ecx(6) : 0;
> -	if (ecx && ~thermal_ecx) {
> -		thermal_ecx &= ecx;
> -		printk("Writing CPUID thermal/power feature mask ECX -> %08Xh\n",
> -		       thermal_ecx);
> -	} else
> -		skip_thermal_ecx = 1;
> -
> - setmask:
> -	/* AMD processors prior to family 10h required a 32-bit password */
> -	if (!skip_feat &&
> -	    wrmsr_amd_safe(MSR_K8_FEATURE_MASK, feat_edx, feat_ecx)) {
> -		skip_feat = 1;
> -		printk("Failed to set CPUID feature mask\n");
> +		if(~(opt_cpuid_mask_ecx & opt_cpuid_mask_edx)) {
> +			ecx &= opt_cpuid_mask_ecx;
> +			edx &= opt_cpuid_mask_edx;
> +		} else if ( m ) {

Bad use of Xen coding style.

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 27/31] xen/x86: Rework Intel masking/faulting setup
  2015-12-16 21:24 ` [PATCH RFC 27/31] xen/x86: Rework Intel masking/faulting setup Andrew Cooper
@ 2016-01-22  9:40   ` Jan Beulich
  2016-01-22 14:09     ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Jan Beulich @ 2016-01-22  9:40 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
> +	if (msr_basic)
> +		__probe_mask_msr(&msr_basic, LCAP_1cd, &cpumask_defaults._1cd);
> +
> +	if (msr_ext)
> +		__probe_mask_msr(&msr_ext, LCAP_e1cd, &cpumask_defaults.e1cd);
> +
> +	if (msr_xsave)
> +		__probe_mask_msr(&msr_xsave, LCAP_Da1, &cpumask_defaults.Da1);
> +
> +	/*
> +	 * Don't bother warning about a mismatch if virtualised.  These MSRs
> +	 * are not architectural and almost never virtualised.
> +	 */
> +	if ((expected_levelling_cap == levelling_caps) ||
> +	    cpu_has_hypervisor)
> +		return;
> +
> +	printk(XENLOG_WARNING "Mismatch between expected (%#x"
> +	       ") and real (%#x) levelling caps: missing %#x\n",
> +	       expected_levelling_cap, levelling_caps,
> +	       (expected_levelling_cap ^ levelling_caps) & levelling_caps);
> +	printk(XENLOG_WARNING "Fam %#x, model %#x expected (%#x/%#x/%#x), "
> +	       "got (%#x/%#x/%#x)\n", c->x86, c->x86_model,
> +	       exp_msr_basic, exp_msr_ext, exp_msr_xsave,
> +	       msr_basic, msr_ext, msr_xsave);

I may not have noticed the same on the AMD patch, but printing
zeros as "missing" MSR indexes seems strange to me. Why not
print the missing MSRs with their textual names, easing cross
referencing with the FlexMigration document?

> +/*
> + * opt_cpuid_mask_ecx/edx: cpuid.1[ecx, edx] feature mask.
> + * For example, E8400[Intel Core 2 Duo Processor series] ecx = 0x0008E3FD,
> + * edx = 0xBFEBFBFF when executing CPUID.EAX = 1 normally. If you want to
> + * 'rev down' to E8400, you can set these values in these Xen boot parameters.
> + */
> +static void __init noinline intel_init_levelling(void)
> +{
> +	if ( !probe_intel_cpuid_faulting() )
> +		probe_masking_msrs();
> +
> +	if ( msr_basic )
> +	{
> +		cpumask_defaults._1cd =
> +			((u64)opt_cpuid_mask_edx << 32) | opt_cpuid_mask_ecx;
> +
> +		if ( !~(opt_cpuid_mask_ecx & opt_cpuid_mask_edx) )
>  			printk("Writing CPUID feature mask ecx:edx -> %08x:%08x\n",
>  			       opt_cpuid_mask_ecx, opt_cpuid_mask_edx);

Are these messages, without adjustment to their wording, not
going to be confusing? After all the intention is to not just write
a single, never modified value. E.g. better "Defaulting ..."?

> @@ -183,22 +237,13 @@ static void early_init_intel(struct cpuinfo_x86 *c)
>  	    (boot_cpu_data.x86_mask == 3 || boot_cpu_data.x86_mask == 4))
>  		paddr_bits = 36;
>  
> -	if (c == &boot_cpu_data && c->x86 == 6) {
> -		if (probe_intel_cpuid_faulting())
> -			__set_bit(X86_FEATURE_CPUID_FAULTING,
> -				  c->x86_capability);
> -	} else if (boot_cpu_has(X86_FEATURE_CPUID_FAULTING)) {
> -		BUG_ON(!probe_intel_cpuid_faulting());
> -		__set_bit(X86_FEATURE_CPUID_FAULTING, c->x86_capability);
> -	}
> +	if (c == &boot_cpu_data)
> +		intel_init_levelling();
> +
> +	if (test_bit(X86_FEATURE_CPUID_FAULTING, boot_cpu_data.x86_capability))
> +            __set_bit(X86_FEATURE_CPUID_FAULTING, c->x86_capability);

So you intentionally delete the validation of CPUID faulting being
available on APs? Also - indentation.

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 28/31] xen/x86: Context switch all levelling state in context_switch()
  2015-12-16 21:24 ` [PATCH RFC 28/31] xen/x86: Context switch all levelling state in context_switch() Andrew Cooper
@ 2016-01-22  9:52   ` Jan Beulich
  2016-01-22 14:19     ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Jan Beulich @ 2016-01-22  9:52 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
> --- a/xen/arch/x86/cpu/amd.c
> +++ b/xen/arch/x86/cpu/amd.c
> @@ -300,6 +300,9 @@ static void __init noinline amd_init_levelling(void)
>  		cpumask_defaults._6c &= (~0ULL << 32);
>  		cpumask_defaults._6c |= ecx;
>  	}
> +
> +        if (levelling_caps)
> +            ctxt_switch_levelling = amd_ctxt_switch_levelling;
>  }

Indentation.

> --- a/xen/arch/x86/cpu/common.c
> +++ b/xen/arch/x86/cpu/common.c
> @@ -86,6 +86,13 @@ static const struct cpu_dev default_cpu = {
>  };
>  static const struct cpu_dev *this_cpu = &default_cpu;
>  
> +void default_ctxt_switch_levelling(const struct domain *nextd)

static

> +{
> +    /* Nop */
> +}
> +void (*ctxt_switch_levelling)(const struct domain *nextd) __read_mostly =
> +    default_ctxt_switch_levelling;

While current and past gcc may accept (and honor) this placement of
the __read_mostly annotation, I think it is wrong from a strict language
syntax pov. Imo it instead ought to be

void (*__read_mostly ctxt_switch_levelling)(const struct domain *nextd) =

Also - indentation again.

> @@ -145,6 +145,13 @@ void intel_ctxt_switch_levelling(const struct domain *nextd)
>  	struct cpumasks *these_masks = &this_cpu(cpumasks);
>  	const struct cpumasks *masks = &cpumask_defaults;
>  
> +	if (cpu_has_cpuid_faulting) {
> +		set_cpuid_faulting(nextd && is_pv_domain(nextd) &&
> +				   !is_control_domain(nextd) &&
> +				   !is_hardware_domain(nextd));
> +		return;
> +	}

Considering that you don't even probe the masking MSRs, this seems
inconsistent with your "always level the entire system" choice. As said
I'm opposed to that (i.e. the code here is fine), but at the very least
things ought to be consistent.

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 29/31] x86/pv: Provide custom cpumasks for PV domains
  2015-12-16 21:24 ` [PATCH RFC 29/31] x86/pv: Provide custom cpumasks for PV domains Andrew Cooper
@ 2016-01-22  9:56   ` Jan Beulich
  2016-01-22 14:24     ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Jan Beulich @ 2016-01-22  9:56 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
> --- a/xen/arch/x86/cpu/amd.c
> +++ b/xen/arch/x86/cpu/amd.c
> @@ -203,7 +203,9 @@ static void __init noinline probe_masking_msrs(void)
>  void amd_ctxt_switch_levelling(const struct domain *nextd)
>  {
>  	struct cpumasks *these_masks = &this_cpu(cpumasks);
> -	const struct cpumasks *masks = &cpumask_defaults;
> +	const struct cpumasks *masks =
> +            (nextd && is_pv_domain(nextd) && nextd->arch.pv_domain.masks)
> +            ? nextd->arch.pv_domain.masks : &cpumask_defaults;

Can nextd really ever be NULL here?

> --- a/xen/arch/x86/domain.c
> +++ b/xen/arch/x86/domain.c
> @@ -578,6 +578,12 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
>              goto fail;
>          clear_page(d->arch.pv_domain.gdt_ldt_l1tab);
>  
> +        d->arch.pv_domain.masks = xmalloc(struct cpumasks);
> +        if ( !d->arch.pv_domain.masks )
> +            goto fail;
> +        memcpy(d->arch.pv_domain.masks, &cpumask_defaults,
> +               sizeof(*d->arch.pv_domain.masks));

Structure assignment, to make the thing type safe?

Also there's a change missing to the cleanup code after the "fail"
label.

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 30/31] x86/domctl: Update PV domain cpumasks when setting cpuid policy
  2015-12-16 21:24 ` [PATCH RFC 30/31] x86/domctl: Update PV domain cpumasks when setting cpuid policy Andrew Cooper
@ 2016-01-22 10:02   ` Jan Beulich
  0 siblings, 0 replies; 123+ messages in thread
From: Jan Beulich @ 2016-01-22 10:02 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:

> --- a/xen/arch/x86/domctl.c
> +++ b/xen/arch/x86/domctl.c
> @@ -77,6 +77,74 @@ static void update_domain_cpuid_info(struct domain *d,
>          d->arch.x86_model = (ctl->eax >> 4) & 0xf;
>          if ( d->arch.x86 >= 0x6 )
>              d->arch.x86_model |= (ctl->eax >> 12) & 0xf0;
> +
> +        if ( is_pv_domain(d) )
> +        {
> +            uint64_t mask = cpumask_defaults._1cd;
> +
> +            if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
> +                mask &= ((uint64_t)ctl->edx << 32) | ctl->ecx;
> +            else if ( boot_cpu_data.x86_vendor == X86_VENDOR_AMD )
> +                mask &= ((uint64_t)ctl->ecx << 32) | ctl->edx;

I'd prefer switch() to be used in cases like this, but anyway
Reviewed-by: Jan Beulich <jbeulich@suse.com>
notwithstanding possible mechanical adjustments to the patch due
to changes to earlier ones.

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 25/31] xen/x86: Common infrastructure for levelling context switching
  2016-01-22  8:56   ` Jan Beulich
@ 2016-01-22 10:05     ` Andrew Cooper
  0 siblings, 0 replies; 123+ messages in thread
From: Andrew Cooper @ 2016-01-22 10:05 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 22/01/16 08:56, Jan Beulich wrote:
>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>> --- a/xen/arch/x86/cpu/common.c
>> +++ b/xen/arch/x86/cpu/common.c
>> @@ -35,6 +35,9 @@ integer_param("cpuid_mask_ext_edx", opt_cpuid_mask_ext_edx);
>>  unsigned int __initdata expected_levelling_cap;
>>  unsigned int __read_mostly levelling_caps;
>>  
>> +DEFINE_PER_CPU(struct cpumasks, cpumasks);
>> +struct cpumasks __read_mostly cpumask_defaults;
> Any reason these can't be introduced when first used? (The question
> really applies to the rest of this patch too, I guess.)

The subsequent two patches are sufficiently complicated in their own
right that I deliberately pulled these bits out.

>
>> --- a/xen/include/asm-x86/processor.h
>> +++ b/xen/include/asm-x86/processor.h
>> @@ -585,6 +585,21 @@ int microcode_resume_cpu(unsigned int cpu);
>>   */
>>  extern unsigned int expected_levelling_cap, levelling_caps;
>>  
>> +struct cpumasks
>> +{
>> +    uint64_t _1cd;
>> +    uint64_t e1cd;
>> +    uint64_t Da1;
>> +    uint64_t _6c;
>> +    uint64_t _7ab0;
>> +};
> While I see the need for these underscore prefixes with the
> current naming scheme, perhaps it would be better to make
> this fully consistent with the acronym #define-s, by e.g.
> prefixing the base ones with 'b'? Such full naming consistency
> would allow for string concatenation in macros, should such a
> possibility ever arise, no matter whether manifest constants
> or structure members here are needed to be accessed.
>
> As to the name of the structure itself - perhaps better
> cpuidmasks?

Ok.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 26/31] xen/x86: Rework AMD masking MSR setup
  2016-01-22  9:27   ` Jan Beulich
@ 2016-01-22 11:01     ` Andrew Cooper
  2016-01-22 11:13       ` Jan Beulich
  0 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2016-01-22 11:01 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 22/01/16 09:27, Jan Beulich wrote:
>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>> This patch is best reviewed as its end result rather than as a diff, as it
>> rewrites almost all of the setup.
> This, I think, doesn't belong in the commit message itself.

Why not? It applies equally to anyone reading the commit in tree.

>
>> @@ -126,126 +133,172 @@ static const struct cpuidmask *__init noinline 
>> get_cpuidmask(const char *opt)
>>  }
>>  
>>  /*
>> - * Mask the features and extended features returned by CPUID.  Parameters are
>> - * set from the boot line via two methods:
>> - *
>> - *   1) Specific processor revision string
>> - *   2) User-defined masks
>> - *
>> - * The processor revision string parameter has precedene.
>> + * Sets caps in expected_levelling_cap, probes for the specified mask MSR, and
>> + * set caps in levelling_caps if it is found.  Processors prior to Fam 10h
>> + * required a 32-bit password for masking MSRs.  Reads the default value into
>> + * msr_val.
>>   */
>> -static void __devinit set_cpuidmask(const struct cpuinfo_x86 *c)
>> +static void __init __probe_mask_msr(unsigned int msr, uint64_t caps,
>> +                                    uint64_t *msr_val)
>>  {
>> -	static unsigned int feat_ecx, feat_edx;
>> -	static unsigned int extfeat_ecx, extfeat_edx;
>> -	static unsigned int l7s0_eax, l7s0_ebx;
>> -	static unsigned int thermal_ecx;
>> -	static bool_t skip_feat, skip_extfeat;
>> -	static bool_t skip_l7s0_eax_ebx, skip_thermal_ecx;
>> -	static enum { not_parsed, no_mask, set_mask } status;
>> -	unsigned int eax, ebx, ecx, edx;
>> -
>> -	if (status == no_mask)
>> -		return;
>> +	unsigned int hi, lo;
>> +
>> +        expected_levelling_cap |= caps;
> Mixing indentation styles.

Yes - sadly some crept in, despite my best efforts.  I have already
fixed all I can find in the series.

>
>> +
>> +	if ((rdmsr_amd_safe(msr, &lo, &hi) == 0) &&
>> +	    (wrmsr_amd_safe(msr, lo, hi) == 0))
>> +		levelling_caps |= caps;
> This logic assumes that faults are possible only because the MSR is
> not there at all, not because of the actual value used. Is this a safe
> assumption, the more that you don't use the "safe" variants
> anymore at runtime?

Yes - it is a safe assumption.

The MSRs on AMD are at fixed indices and all specified to cover the full
32bit of a cpuid feature leaf.  All we really care about is whether the
MSR is present (and to read its defaults, if it is).

If the MSR isn't present, levelling_caps won't be updated, and Xen will
never touch the MSR again.

>
>> +/*
>> + * Probe for the existance of the expected masking MSRs.  They might easily
>> + * not be available if Xen is running virtualised.
>> + */
>> +static void __init noinline probe_masking_msrs(void)
>> +{
>> +	const struct cpuinfo_x86 *c = &boot_cpu_data;
>>  
>> -	ASSERT((status == not_parsed) && (c == &boot_cpu_data));
>> -	status = no_mask;
>> +	/*
>> +	 * First, work out which masking MSRs we should have, based on
>> +	 * revision and cpuid.
>> +	 */
>>  
>>  	/* Fam11 doesn't support masking at all. */
>>  	if (c->x86 == 0x11)
>>  		return;
>>  
>> -	if (~(opt_cpuid_mask_ecx & opt_cpuid_mask_edx &
>> -	      opt_cpuid_mask_ext_ecx & opt_cpuid_mask_ext_edx &
>> -	      opt_cpuid_mask_l7s0_eax & opt_cpuid_mask_l7s0_ebx &
>> -	      opt_cpuid_mask_thermal_ecx)) {
>> -		feat_ecx = opt_cpuid_mask_ecx;
>> -		feat_edx = opt_cpuid_mask_edx;
>> -		extfeat_ecx = opt_cpuid_mask_ext_ecx;
>> -		extfeat_edx = opt_cpuid_mask_ext_edx;
>> -		l7s0_eax = opt_cpuid_mask_l7s0_eax;
>> -		l7s0_ebx = opt_cpuid_mask_l7s0_ebx;
>> -		thermal_ecx = opt_cpuid_mask_thermal_ecx;
>> -	} else if (*opt_famrev == '\0') {
>> +	__probe_mask_msr(MSR_K8_FEATURE_MASK, LCAP_1cd,
>> +			 &cpumask_defaults._1cd);
>> +	__probe_mask_msr(MSR_K8_EXT_FEATURE_MASK, LCAP_e1cd,
>> +			 &cpumask_defaults.e1cd);
>> +
>> +	if (c->cpuid_level >= 7)
>> +		__probe_mask_msr(MSR_AMD_L7S0_FEATURE_MASK, LCAP_7ab0,
>> +				 &cpumask_defaults._7ab0);
>> +
>> +	if (c->x86 == 0x15 && c->cpuid_level >= 6 && cpuid_ecx(6))
>> +		__probe_mask_msr(MSR_AMD_THRM_FEATURE_MASK, LCAP_6c,
>> +				 &cpumask_defaults._6c);
>> +
>> +	/*
>> +	 * Don't bother warning about a mismatch if virtualised.  These MSRs
>> +	 * are not architectural and almost never virtualised.
>> +	 */
>> +	if ((expected_levelling_cap == levelling_caps) ||
>> +	    cpu_has_hypervisor)
>>  		return;
>> -	} else {
>> -		const struct cpuidmask *m = get_cpuidmask(opt_famrev);
>> +
>> +	printk(XENLOG_WARNING "Mismatch between expected (%#x"
>> +	       ") and real (%#x) levelling caps: missing %#x\n",
> Breaking a format string inside parentheses is certainly a little odd.
> Also I don't think the "missing" part is really useful, considering that
> you already print both values used in its calculation.

Not everyone can do multi-stage 32bit hex arithmetic in their head.

With the current number ranges here, it is probably ok, but I wish to
avoid it turning into error messages such as we have in hvm cr4
auditing, where it definitely takes some thought to decode.

Or in other words, its no harm to provide and short-circuits the first
step required in debugging the issue.

>
>> +	       expected_levelling_cap, levelling_caps,
>> +	       (expected_levelling_cap ^ levelling_caps) & levelling_caps);
>> +	printk(XENLOG_WARNING "Fam %#x, model %#x level %#x\n",
>> +	       c->x86, c->x86_model, c->cpuid_level);
>> +	printk(XENLOG_WARNING
>> +	       "If not running virtualised, please report a bug\n");
> Well - you checked for running virtualized, so making it here when
> running virtualized is already a bug (albeit not in the code here)?

Why would it be a bug?  The virtualising environment might provide these
MSRs, in which case we should use them.

It is just that a virtualising environment usually doesn't, at which
point we shouldn't complain to the user that Xen's heuristics for
determining the masking set needs updating.

>
>> +void amd_ctxt_switch_levelling(const struct domain *nextd)
>> +{
>> +	struct cpumasks *these_masks = &this_cpu(cpumasks);
>> +	const struct cpumasks *masks = &cpumask_defaults;
>> +
>> +#define LAZY(cap, msr, field)						\
>> +	({								\
>> +		if ( ((levelling_caps & cap) == cap) &&			\
>> +		     (these_masks->field != masks->field) )		\
>> +		{							\
>> +			wrmsr_amd(msr, masks->field);			\
>> +			these_masks->field = masks->field;		\
>> +		}							\
>> +	})
>> +
>> +	LAZY(LCAP_1cd,  MSR_K8_FEATURE_MASK,       _1cd);
>> +	LAZY(LCAP_e1cd, MSR_K8_EXT_FEATURE_MASK,   e1cd);
>> +	LAZY(LCAP_7ab0, MSR_AMD_L7S0_FEATURE_MASK, _7ab0);
>> +	LAZY(LCAP_6c,   MSR_AMD_THRM_FEATURE_MASK, _6c);
> So here we already have the first example where fully consistent
> naming would allow elimination of a macro parameter.

Token concatenation deliberately obscures code from tool like grep and
cscope.  There is already too much of the Xen source code obscured like
this; I'd prefer not to add to it.

>
> And then, how is this supposed to work? You only restore defaults,
> but never write non-default values. Namely, nextd is an unused
> function parameter ...
>
> Also I guess my comment about adding unused code needs
> repeating here.

Future patches build on this, both using the parameter, and not using
the defaults.

I am also certain that if I did two patches, the first putting in a void
function, and the second changing it to a pointer, your review would ask
me to turn it into this.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 26/31] xen/x86: Rework AMD masking MSR setup
  2016-01-22 11:01     ` Andrew Cooper
@ 2016-01-22 11:13       ` Jan Beulich
  2016-01-22 13:59         ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Jan Beulich @ 2016-01-22 11:13 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 22.01.16 at 12:01, <andrew.cooper3@citrix.com> wrote:
> On 22/01/16 09:27, Jan Beulich wrote:
>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>> +	       expected_levelling_cap, levelling_caps,
>>> +	       (expected_levelling_cap ^ levelling_caps) & levelling_caps);
>>> +	printk(XENLOG_WARNING "Fam %#x, model %#x level %#x\n",
>>> +	       c->x86, c->x86_model, c->cpuid_level);
>>> +	printk(XENLOG_WARNING
>>> +	       "If not running virtualised, please report a bug\n");
>> Well - you checked for running virtualized, so making it here when
>> running virtualized is already a bug (albeit not in the code here)?
> 
> Why would it be a bug?  The virtualising environment might provide these
> MSRs, in which case we should use them.

Because you won't make it here when cpu_has_hypervisor.

>>> +void amd_ctxt_switch_levelling(const struct domain *nextd)
>>> +{
>>> +	struct cpumasks *these_masks = &this_cpu(cpumasks);
>>> +	const struct cpumasks *masks = &cpumask_defaults;
>>> +
>>> +#define LAZY(cap, msr, field)						\
>>> +	({								\
>>> +		if ( ((levelling_caps & cap) == cap) &&			\
>>> +		     (these_masks->field != masks->field) )		\
>>> +		{							\
>>> +			wrmsr_amd(msr, masks->field);			\
>>> +			these_masks->field = masks->field;		\
>>> +		}							\
>>> +	})
>>> +
>>> +	LAZY(LCAP_1cd,  MSR_K8_FEATURE_MASK,       _1cd);
>>> +	LAZY(LCAP_e1cd, MSR_K8_EXT_FEATURE_MASK,   e1cd);
>>> +	LAZY(LCAP_7ab0, MSR_AMD_L7S0_FEATURE_MASK, _7ab0);
>>> +	LAZY(LCAP_6c,   MSR_AMD_THRM_FEATURE_MASK, _6c);
>> So here we already have the first example where fully consistent
>> naming would allow elimination of a macro parameter.
> 
> Token concatenation deliberately obscures code from tool like grep and
> cscope.  There is already too much of the Xen source code obscured like
> this; I'd prefer not to add to it.

I'm not sure grep-abilty is more important than code readability.
My personal opinion surely is that the latter is more important.

>> And then, how is this supposed to work? You only restore defaults,
>> but never write non-default values. Namely, nextd is an unused
>> function parameter ...
>>
>> Also I guess my comment about adding unused code needs
>> repeating here.
> 
> Future patches build on this, both using the parameter, and not using
> the defaults.
> 
> I am also certain that if I did two patches, the first putting in a void
> function, and the second changing it to a pointer, your review would ask
> me to turn it into this.

Well, I realize things will all make sense by the end of the series, but
honestly in some of the cases I'm not sure the split between patches
was well done. But just to be clear, none of the related comments
mean I would outright reject any of the patches just for that reason.

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 26/31] xen/x86: Rework AMD masking MSR setup
  2016-01-22 11:13       ` Jan Beulich
@ 2016-01-22 13:59         ` Andrew Cooper
  2016-01-22 14:12           ` Jan Beulich
  0 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2016-01-22 13:59 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 22/01/16 11:13, Jan Beulich wrote:
>>>> On 22.01.16 at 12:01, <andrew.cooper3@citrix.com> wrote:
>> On 22/01/16 09:27, Jan Beulich wrote:
>>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>>> +	       expected_levelling_cap, levelling_caps,
>>>> +	       (expected_levelling_cap ^ levelling_caps) & levelling_caps);
>>>> +	printk(XENLOG_WARNING "Fam %#x, model %#x level %#x\n",
>>>> +	       c->x86, c->x86_model, c->cpuid_level);
>>>> +	printk(XENLOG_WARNING
>>>> +	       "If not running virtualised, please report a bug\n");
>>> Well - you checked for running virtualized, so making it here when
>>> running virtualized is already a bug (albeit not in the code here)?
>> Why would it be a bug?  The virtualising environment might provide these
>> MSRs, in which case we should use them.
> Because you won't make it here when cpu_has_hypervisor.

Not all hypervisors advertise themselves with the hypervisor bit.  Some
versions of HyperV and ESXi will panic if they see a hypervisor bit, so
virtualisation software needs to hide the hypervisor bit to successfully
visualise some software.

The user reading Xen's error message is in a better position to judge
when Xen is actually virtualised, because Xen is not able to say with
certainty.

>
>>>> +void amd_ctxt_switch_levelling(const struct domain *nextd)
>>>> +{
>>>> +	struct cpumasks *these_masks = &this_cpu(cpumasks);
>>>> +	const struct cpumasks *masks = &cpumask_defaults;
>>>> +
>>>> +#define LAZY(cap, msr, field)						\
>>>> +	({								\
>>>> +		if ( ((levelling_caps & cap) == cap) &&			\
>>>> +		     (these_masks->field != masks->field) )		\
>>>> +		{							\
>>>> +			wrmsr_amd(msr, masks->field);			\
>>>> +			these_masks->field = masks->field;		\
>>>> +		}							\
>>>> +	})
>>>> +
>>>> +	LAZY(LCAP_1cd,  MSR_K8_FEATURE_MASK,       _1cd);
>>>> +	LAZY(LCAP_e1cd, MSR_K8_EXT_FEATURE_MASK,   e1cd);
>>>> +	LAZY(LCAP_7ab0, MSR_AMD_L7S0_FEATURE_MASK, _7ab0);
>>>> +	LAZY(LCAP_6c,   MSR_AMD_THRM_FEATURE_MASK, _6c);
>>> So here we already have the first example where fully consistent
>>> naming would allow elimination of a macro parameter.
>> Token concatenation deliberately obscures code from tool like grep and
>> cscope.  There is already too much of the Xen source code obscured like
>> this; I'd prefer not to add to it.
> I'm not sure grep-abilty is more important than code readability.
> My personal opinion surely is that the latter is more important.

It doesn't matter how readable the code is if you can't find it again later.

And in this case, the difference between 2 and 3 macro parameters
doesn't affect the readability of the code.  All context is available in
the preceding 10 lines.

>
>>> And then, how is this supposed to work? You only restore defaults,
>>> but never write non-default values. Namely, nextd is an unused
>>> function parameter ...
>>>
>>> Also I guess my comment about adding unused code needs
>>> repeating here.
>> Future patches build on this, both using the parameter, and not using
>> the defaults.
>>
>> I am also certain that if I did two patches, the first putting in a void
>> function, and the second changing it to a pointer, your review would ask
>> me to turn it into this.
> Well, I realize things will all make sense by the end of the series, but
> honestly in some of the cases I'm not sure the split between patches
> was well done.

If you can suggest a better ordering then I am all ears.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 27/31] xen/x86: Rework Intel masking/faulting setup
  2016-01-22  9:40   ` Jan Beulich
@ 2016-01-22 14:09     ` Andrew Cooper
  2016-01-22 14:29       ` Jan Beulich
  0 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2016-01-22 14:09 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 22/01/16 09:40, Jan Beulich wrote:
>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>> +	if (msr_basic)
>> +		__probe_mask_msr(&msr_basic, LCAP_1cd, &cpumask_defaults._1cd);
>> +
>> +	if (msr_ext)
>> +		__probe_mask_msr(&msr_ext, LCAP_e1cd, &cpumask_defaults.e1cd);
>> +
>> +	if (msr_xsave)
>> +		__probe_mask_msr(&msr_xsave, LCAP_Da1, &cpumask_defaults.Da1);
>> +
>> +	/*
>> +	 * Don't bother warning about a mismatch if virtualised.  These MSRs
>> +	 * are not architectural and almost never virtualised.
>> +	 */
>> +	if ((expected_levelling_cap == levelling_caps) ||
>> +	    cpu_has_hypervisor)
>> +		return;
>> +
>> +	printk(XENLOG_WARNING "Mismatch between expected (%#x"
>> +	       ") and real (%#x) levelling caps: missing %#x\n",
>> +	       expected_levelling_cap, levelling_caps,
>> +	       (expected_levelling_cap ^ levelling_caps) & levelling_caps);
>> +	printk(XENLOG_WARNING "Fam %#x, model %#x expected (%#x/%#x/%#x), "
>> +	       "got (%#x/%#x/%#x)\n", c->x86, c->x86_model,
>> +	       exp_msr_basic, exp_msr_ext, exp_msr_xsave,
>> +	       msr_basic, msr_ext, msr_xsave);
> I may not have noticed the same on the AMD patch, but printing
> zeros as "missing" MSR indexes seems strange to me. Why not
> print the missing MSRs with their textual names, easing cross
> referencing with the FlexMigration document?

AMD and Intel are different in this regard.  AMD's masking MSRs are at
fixed addresses, while Intel's vary MSR address by generation, which is
why I stored the probed address in a variable.

There are not consistent names available.  In this case, I think the
numbers are actually clearer than the names.

>
>> +/*
>> + * opt_cpuid_mask_ecx/edx: cpuid.1[ecx, edx] feature mask.
>> + * For example, E8400[Intel Core 2 Duo Processor series] ecx = 0x0008E3FD,
>> + * edx = 0xBFEBFBFF when executing CPUID.EAX = 1 normally. If you want to
>> + * 'rev down' to E8400, you can set these values in these Xen boot parameters.
>> + */
>> +static void __init noinline intel_init_levelling(void)
>> +{
>> +	if ( !probe_intel_cpuid_faulting() )
>> +		probe_masking_msrs();
>> +
>> +	if ( msr_basic )
>> +	{
>> +		cpumask_defaults._1cd =
>> +			((u64)opt_cpuid_mask_edx << 32) | opt_cpuid_mask_ecx;
>> +
>> +		if ( !~(opt_cpuid_mask_ecx & opt_cpuid_mask_edx) )
>>  			printk("Writing CPUID feature mask ecx:edx -> %08x:%08x\n",
>>  			       opt_cpuid_mask_ecx, opt_cpuid_mask_edx);
> Are these messages, without adjustment to their wording, not
> going to be confusing? After all the intention is to not just write
> a single, never modified value. E.g. better "Defaulting ..."?

I will change the wording.  It would be better than confusing a new
different meaning with the old written message.

>
>> @@ -183,22 +237,13 @@ static void early_init_intel(struct cpuinfo_x86 *c)
>>  	    (boot_cpu_data.x86_mask == 3 || boot_cpu_data.x86_mask == 4))
>>  		paddr_bits = 36;
>>  
>> -	if (c == &boot_cpu_data && c->x86 == 6) {
>> -		if (probe_intel_cpuid_faulting())
>> -			__set_bit(X86_FEATURE_CPUID_FAULTING,
>> -				  c->x86_capability);
>> -	} else if (boot_cpu_has(X86_FEATURE_CPUID_FAULTING)) {
>> -		BUG_ON(!probe_intel_cpuid_faulting());
>> -		__set_bit(X86_FEATURE_CPUID_FAULTING, c->x86_capability);
>> -	}
>> +	if (c == &boot_cpu_data)
>> +		intel_init_levelling();
>> +
>> +	if (test_bit(X86_FEATURE_CPUID_FAULTING, boot_cpu_data.x86_capability))
>> +            __set_bit(X86_FEATURE_CPUID_FAULTING, c->x86_capability);
> So you intentionally delete the validation of CPUID faulting being
> available on APs?

Yes.  All this does is change where Xen crashes, in the case that AP's
have different capabilities to the BSP, and allows more startup code to
move into __init.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 26/31] xen/x86: Rework AMD masking MSR setup
  2016-01-22 13:59         ` Andrew Cooper
@ 2016-01-22 14:12           ` Jan Beulich
  2016-01-22 17:03             ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Jan Beulich @ 2016-01-22 14:12 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 22.01.16 at 14:59, <andrew.cooper3@citrix.com> wrote:
> On 22/01/16 11:13, Jan Beulich wrote:
>>>>> On 22.01.16 at 12:01, <andrew.cooper3@citrix.com> wrote:
>>> On 22/01/16 09:27, Jan Beulich wrote:
>>>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>>>> +	       expected_levelling_cap, levelling_caps,
>>>>> +	       (expected_levelling_cap ^ levelling_caps) & levelling_caps);
>>>>> +	printk(XENLOG_WARNING "Fam %#x, model %#x level %#x\n",
>>>>> +	       c->x86, c->x86_model, c->cpuid_level);
>>>>> +	printk(XENLOG_WARNING
>>>>> +	       "If not running virtualised, please report a bug\n");
>>>> Well - you checked for running virtualized, so making it here when
>>>> running virtualized is already a bug (albeit not in the code here)?
>>> Why would it be a bug?  The virtualising environment might provide these
>>> MSRs, in which case we should use them.
>> Because you won't make it here when cpu_has_hypervisor.
> 
> Not all hypervisors advertise themselves with the hypervisor bit.  Some
> versions of HyperV and ESXi will panic if they see a hypervisor bit, so
> virtualisation software needs to hide the hypervisor bit to successfully
> visualise some software.

Well, but that's the bug I talk of: Not setting that CPUID bit is
not following the spec, and forcing it off to make some code work
in a virtualized environment isn't much better.

> The user reading Xen's error message is in a better position to judge
> when Xen is actually virtualised, because Xen is not able to say with
> certainty.

Okay, okay, bit that way then.

>>>> And then, how is this supposed to work? You only restore defaults,
>>>> but never write non-default values. Namely, nextd is an unused
>>>> function parameter ...
>>>>
>>>> Also I guess my comment about adding unused code needs
>>>> repeating here.
>>> Future patches build on this, both using the parameter, and not using
>>> the defaults.
>>>
>>> I am also certain that if I did two patches, the first putting in a void
>>> function, and the second changing it to a pointer, your review would ask
>>> me to turn it into this.
>> Well, I realize things will all make sense by the end of the series, but
>> honestly in some of the cases I'm not sure the split between patches
>> was well done.
> 
> If you can suggest a better ordering then I am all ears.

For example, move all the context switch logic into the patch
actually invoking the new hook. That still leaves more than
enough in the AMD and Intel rework patches.

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 28/31] xen/x86: Context switch all levelling state in context_switch()
  2016-01-22  9:52   ` Jan Beulich
@ 2016-01-22 14:19     ` Andrew Cooper
  2016-01-22 14:31       ` Jan Beulich
  0 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2016-01-22 14:19 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 22/01/16 09:52, Jan Beulich wrote:
>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>> --- a/xen/arch/x86/cpu/amd.c
>> +++ b/xen/arch/x86/cpu/amd.c
>> @@ -300,6 +300,9 @@ static void __init noinline amd_init_levelling(void)
>>  		cpumask_defaults._6c &= (~0ULL << 32);
>>  		cpumask_defaults._6c |= ecx;
>>  	}
>> +
>> +        if (levelling_caps)
>> +            ctxt_switch_levelling = amd_ctxt_switch_levelling;
>>  }
> Indentation.
>
>> --- a/xen/arch/x86/cpu/common.c
>> +++ b/xen/arch/x86/cpu/common.c
>> @@ -86,6 +86,13 @@ static const struct cpu_dev default_cpu = {
>>  };
>>  static const struct cpu_dev *this_cpu = &default_cpu;
>>  
>> +void default_ctxt_switch_levelling(const struct domain *nextd)
> static
>
>> +{
>> +    /* Nop */
>> +}
>> +void (*ctxt_switch_levelling)(const struct domain *nextd) __read_mostly =
>> +    default_ctxt_switch_levelling;
> While current and past gcc may accept (and honor) this placement of
> the __read_mostly annotation, I think it is wrong from a strict language
> syntax pov. Imo it instead ought to be
>
> void (*__read_mostly ctxt_switch_levelling)(const struct domain *nextd) =
>
> Also - indentation again.
>
>> @@ -145,6 +145,13 @@ void intel_ctxt_switch_levelling(const struct domain *nextd)
>>  	struct cpumasks *these_masks = &this_cpu(cpumasks);
>>  	const struct cpumasks *masks = &cpumask_defaults;
>>  
>> +	if (cpu_has_cpuid_faulting) {
>> +		set_cpuid_faulting(nextd && is_pv_domain(nextd) &&
>> +				   !is_control_domain(nextd) &&
>> +				   !is_hardware_domain(nextd));
>> +		return;
>> +	}
> Considering that you don't even probe the masking MSRs, this seems
> inconsistent with your "always level the entire system" choice.

In the case that faulting is available, we never want to touch masking. 
Faulting is newer and strictly superior to masking.

As documented, there is no hardware which support both.  (In reality,
there is one SKU of IvyBridge CPUs which experimentally have both.)


The fact that dom0 and the hardware domain are bypassed is a bug IMO. 
However, I am preserving the existing behaviour until phase 2 when I fix
other parts of the cpuid policy.  Currently imposing faulting on dom0
causes carnage because nothing generates it a sane policy.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 29/31] x86/pv: Provide custom cpumasks for PV domains
  2016-01-22  9:56   ` Jan Beulich
@ 2016-01-22 14:24     ` Andrew Cooper
  2016-01-22 14:33       ` Jan Beulich
  0 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2016-01-22 14:24 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 22/01/16 09:56, Jan Beulich wrote:
>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>> --- a/xen/arch/x86/cpu/amd.c
>> +++ b/xen/arch/x86/cpu/amd.c
>> @@ -203,7 +203,9 @@ static void __init noinline probe_masking_msrs(void)
>>  void amd_ctxt_switch_levelling(const struct domain *nextd)
>>  {
>>  	struct cpumasks *these_masks = &this_cpu(cpumasks);
>> -	const struct cpumasks *masks = &cpumask_defaults;
>> +	const struct cpumasks *masks =
>> +            (nextd && is_pv_domain(nextd) && nextd->arch.pv_domain.masks)
>> +            ? nextd->arch.pv_domain.masks : &cpumask_defaults;
> Can nextd really ever be NULL here?

Yes, when using this function to set the defaults in the first place
during AP bringup.  Care also needs to be taken on the BSP where current
isn't valid either.

>
>> --- a/xen/arch/x86/domain.c
>> +++ b/xen/arch/x86/domain.c
>> @@ -578,6 +578,12 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
>>              goto fail;
>>          clear_page(d->arch.pv_domain.gdt_ldt_l1tab);
>>  
>> +        d->arch.pv_domain.masks = xmalloc(struct cpumasks);
>> +        if ( !d->arch.pv_domain.masks )
>> +            goto fail;
>> +        memcpy(d->arch.pv_domain.masks, &cpumask_defaults,
>> +               sizeof(*d->arch.pv_domain.masks));
> Structure assignment, to make the thing type safe?
>
> Also there's a change missing to the cleanup code after the "fail"
> label.

What change are you thinking of?  I suppose an xfree() wouldn't go amis,
to prevent a problem for whomever introduces a new failure path, but I
don't see a bug in the code as-is.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 27/31] xen/x86: Rework Intel masking/faulting setup
  2016-01-22 14:09     ` Andrew Cooper
@ 2016-01-22 14:29       ` Jan Beulich
  2016-01-22 14:46         ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Jan Beulich @ 2016-01-22 14:29 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 22.01.16 at 15:09, <andrew.cooper3@citrix.com> wrote:
> On 22/01/16 09:40, Jan Beulich wrote:
>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>> @@ -183,22 +237,13 @@ static void early_init_intel(struct cpuinfo_x86 *c)
>>>  	    (boot_cpu_data.x86_mask == 3 || boot_cpu_data.x86_mask == 4))
>>>  		paddr_bits = 36;
>>>  
>>> -	if (c == &boot_cpu_data && c->x86 == 6) {
>>> -		if (probe_intel_cpuid_faulting())
>>> -			__set_bit(X86_FEATURE_CPUID_FAULTING,
>>> -				  c->x86_capability);
>>> -	} else if (boot_cpu_has(X86_FEATURE_CPUID_FAULTING)) {
>>> -		BUG_ON(!probe_intel_cpuid_faulting());
>>> -		__set_bit(X86_FEATURE_CPUID_FAULTING, c->x86_capability);
>>> -	}
>>> +	if (c == &boot_cpu_data)
>>> +		intel_init_levelling();
>>> +
>>> +	if (test_bit(X86_FEATURE_CPUID_FAULTING, boot_cpu_data.x86_capability))
>>> +            __set_bit(X86_FEATURE_CPUID_FAULTING, c->x86_capability);
>> So you intentionally delete the validation of CPUID faulting being
>> available on APs?
> 
> Yes.  All this does is change where Xen crashes, in the case that AP's
> have different capabilities to the BSP, and allows more startup code to
> move into __init.

So where did that Xen crash point move to (since I didn't spot it)?

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 28/31] xen/x86: Context switch all levelling state in context_switch()
  2016-01-22 14:19     ` Andrew Cooper
@ 2016-01-22 14:31       ` Jan Beulich
  2016-01-22 14:39         ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Jan Beulich @ 2016-01-22 14:31 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 22.01.16 at 15:19, <andrew.cooper3@citrix.com> wrote:
> On 22/01/16 09:52, Jan Beulich wrote:
>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>> @@ -145,6 +145,13 @@ void intel_ctxt_switch_levelling(const struct domain *nextd)
>>>  	struct cpumasks *these_masks = &this_cpu(cpumasks);
>>>  	const struct cpumasks *masks = &cpumask_defaults;
>>>  
>>> +	if (cpu_has_cpuid_faulting) {
>>> +		set_cpuid_faulting(nextd && is_pv_domain(nextd) &&
>>> +				   !is_control_domain(nextd) &&
>>> +				   !is_hardware_domain(nextd));
>>> +		return;
>>> +	}
>> Considering that you don't even probe the masking MSRs, this seems
>> inconsistent with your "always level the entire system" choice.
> 
> In the case that faulting is available, we never want to touch masking. 
> Faulting is newer and strictly superior to masking.
> 
> As documented, there is no hardware which support both.  (In reality,
> there is one SKU of IvyBridge CPUs which experimentally have both.)
> 
> 
> The fact that dom0 and the hardware domain are bypassed is a bug IMO. 

And we appear to disagree here. I'd rather see the rest of the
series match this current behavior.

> However, I am preserving the existing behaviour until phase 2 when I fix
> other parts of the cpuid policy.  Currently imposing faulting on dom0
> causes carnage because nothing generates it a sane policy.
> 
> ~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 29/31] x86/pv: Provide custom cpumasks for PV domains
  2016-01-22 14:24     ` Andrew Cooper
@ 2016-01-22 14:33       ` Jan Beulich
  2016-01-22 14:42         ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Jan Beulich @ 2016-01-22 14:33 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 22.01.16 at 15:24, <andrew.cooper3@citrix.com> wrote:
> On 22/01/16 09:56, Jan Beulich wrote:
>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>> --- a/xen/arch/x86/cpu/amd.c
>>> +++ b/xen/arch/x86/cpu/amd.c
>>> @@ -203,7 +203,9 @@ static void __init noinline probe_masking_msrs(void)
>>>  void amd_ctxt_switch_levelling(const struct domain *nextd)
>>>  {
>>>  	struct cpumasks *these_masks = &this_cpu(cpumasks);
>>> -	const struct cpumasks *masks = &cpumask_defaults;
>>> +	const struct cpumasks *masks =
>>> +            (nextd && is_pv_domain(nextd) && nextd->arch.pv_domain.masks)
>>> +            ? nextd->arch.pv_domain.masks : &cpumask_defaults;
>> Can nextd really ever be NULL here?
> 
> Yes, when using this function to set the defaults in the first place
> during AP bringup.

Ah, I then didn't spot this second use.

>>> --- a/xen/arch/x86/domain.c
>>> +++ b/xen/arch/x86/domain.c
>>> @@ -578,6 +578,12 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
>>>              goto fail;
>>>          clear_page(d->arch.pv_domain.gdt_ldt_l1tab);
>>>  
>>> +        d->arch.pv_domain.masks = xmalloc(struct cpumasks);
>>> +        if ( !d->arch.pv_domain.masks )
>>> +            goto fail;
>>> +        memcpy(d->arch.pv_domain.masks, &cpumask_defaults,
>>> +               sizeof(*d->arch.pv_domain.masks));
>> Structure assignment, to make the thing type safe?
>>
>> Also there's a change missing to the cleanup code after the "fail"
>> label.
> 
> What change are you thinking of?  I suppose an xfree() wouldn't go amis,
> to prevent a problem for whomever introduces a new failure path, but I
> don't see a bug in the code as-is.

I don't understand this second sentence. It's the missing addition
of a matching xfree() that my comment was about.

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 28/31] xen/x86: Context switch all levelling state in context_switch()
  2016-01-22 14:31       ` Jan Beulich
@ 2016-01-22 14:39         ` Andrew Cooper
  0 siblings, 0 replies; 123+ messages in thread
From: Andrew Cooper @ 2016-01-22 14:39 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 22/01/16 14:31, Jan Beulich wrote:
>>>> On 22.01.16 at 15:19, <andrew.cooper3@citrix.com> wrote:
>> On 22/01/16 09:52, Jan Beulich wrote:
>>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>>> @@ -145,6 +145,13 @@ void intel_ctxt_switch_levelling(const struct domain *nextd)
>>>>  	struct cpumasks *these_masks = &this_cpu(cpumasks);
>>>>  	const struct cpumasks *masks = &cpumask_defaults;
>>>>  
>>>> +	if (cpu_has_cpuid_faulting) {
>>>> +		set_cpuid_faulting(nextd && is_pv_domain(nextd) &&
>>>> +				   !is_control_domain(nextd) &&
>>>> +				   !is_hardware_domain(nextd));
>>>> +		return;
>>>> +	}
>>> Considering that you don't even probe the masking MSRs, this seems
>>> inconsistent with your "always level the entire system" choice.
>> In the case that faulting is available, we never want to touch masking. 
>> Faulting is newer and strictly superior to masking.
>>
>> As documented, there is no hardware which support both.  (In reality,
>> there is one SKU of IvyBridge CPUs which experimentally have both.)
>>
>>
>> The fact that dom0 and the hardware domain are bypassed is a bug IMO. 
> And we appear to disagree here. I'd rather see the rest of the
> series match this current behavior.

I am planning to fix it, but it is the same quantity of work again, on
top of this series.  I am deliberately not conflating all of the cpuid
related fixes into one series, because it is simply too much work to do
in one go.

Dom0 still gets its "feature levelled" system via emulated cpuid, just
as it does at the moment.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 29/31] x86/pv: Provide custom cpumasks for PV domains
  2016-01-22 14:33       ` Jan Beulich
@ 2016-01-22 14:42         ` Andrew Cooper
  2016-01-22 14:48           ` Jan Beulich
  0 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2016-01-22 14:42 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 22/01/16 14:33, Jan Beulich wrote:
>>>> On 22.01.16 at 15:24, <andrew.cooper3@citrix.com> wrote:
>> On 22/01/16 09:56, Jan Beulich wrote:
>>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>>> --- a/xen/arch/x86/cpu/amd.c
>>>> +++ b/xen/arch/x86/cpu/amd.c
>>>> @@ -203,7 +203,9 @@ static void __init noinline probe_masking_msrs(void)
>>>>  void amd_ctxt_switch_levelling(const struct domain *nextd)
>>>>  {
>>>>  	struct cpumasks *these_masks = &this_cpu(cpumasks);
>>>> -	const struct cpumasks *masks = &cpumask_defaults;
>>>> +	const struct cpumasks *masks =
>>>> +            (nextd && is_pv_domain(nextd) && nextd->arch.pv_domain.masks)
>>>> +            ? nextd->arch.pv_domain.masks : &cpumask_defaults;
>>> Can nextd really ever be NULL here?
>> Yes, when using this function to set the defaults in the first place
>> during AP bringup.
> Ah, I then didn't spot this second use.
>
>>>> --- a/xen/arch/x86/domain.c
>>>> +++ b/xen/arch/x86/domain.c
>>>> @@ -578,6 +578,12 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
>>>>              goto fail;
>>>>          clear_page(d->arch.pv_domain.gdt_ldt_l1tab);
>>>>  
>>>> +        d->arch.pv_domain.masks = xmalloc(struct cpumasks);
>>>> +        if ( !d->arch.pv_domain.masks )
>>>> +            goto fail;
>>>> +        memcpy(d->arch.pv_domain.masks, &cpumask_defaults,
>>>> +               sizeof(*d->arch.pv_domain.masks));
>>> Structure assignment, to make the thing type safe?
>>>
>>> Also there's a change missing to the cleanup code after the "fail"
>>> label.
>> What change are you thinking of?  I suppose an xfree() wouldn't go amis,
>> to prevent a problem for whomever introduces a new failure path, but I
>> don't see a bug in the code as-is.
> I don't understand this second sentence. It's the missing addition
> of a matching xfree() that my comment was about.

All "goto fails;" are visible in this context.  As the code currently
stands, there is not a failure path where the allocation isn't freed.

The point of my second sentence is that this would be a latent bug if
someone introduced another failure path, which is why I will fix it.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 27/31] xen/x86: Rework Intel masking/faulting setup
  2016-01-22 14:29       ` Jan Beulich
@ 2016-01-22 14:46         ` Andrew Cooper
  2016-01-22 14:53           ` Jan Beulich
  0 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2016-01-22 14:46 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 22/01/16 14:29, Jan Beulich wrote:
>>>> On 22.01.16 at 15:09, <andrew.cooper3@citrix.com> wrote:
>> On 22/01/16 09:40, Jan Beulich wrote:
>>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>>> @@ -183,22 +237,13 @@ static void early_init_intel(struct cpuinfo_x86 *c)
>>>>  	    (boot_cpu_data.x86_mask == 3 || boot_cpu_data.x86_mask == 4))
>>>>  		paddr_bits = 36;
>>>>  
>>>> -	if (c == &boot_cpu_data && c->x86 == 6) {
>>>> -		if (probe_intel_cpuid_faulting())
>>>> -			__set_bit(X86_FEATURE_CPUID_FAULTING,
>>>> -				  c->x86_capability);
>>>> -	} else if (boot_cpu_has(X86_FEATURE_CPUID_FAULTING)) {
>>>> -		BUG_ON(!probe_intel_cpuid_faulting());
>>>> -		__set_bit(X86_FEATURE_CPUID_FAULTING, c->x86_capability);
>>>> -	}
>>>> +	if (c == &boot_cpu_data)
>>>> +		intel_init_levelling();
>>>> +
>>>> +	if (test_bit(X86_FEATURE_CPUID_FAULTING, boot_cpu_data.x86_capability))
>>>> +            __set_bit(X86_FEATURE_CPUID_FAULTING, c->x86_capability);
>>> So you intentionally delete the validation of CPUID faulting being
>>> available on APs?
>> Yes.  All this does is change where Xen crashes, in the case that AP's
>> have different capabilities to the BSP, and allows more startup code to
>> move into __init.
> So where did that Xen crash point move to (since I didn't spot it)?

set_cpuid_faulting() doesn't use safe MSR accesses, so would crash on
first use in a mixed setup.

I could extend it to ASSERT(cpu_has_cpuid_faulting) if you would prefer.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 29/31] x86/pv: Provide custom cpumasks for PV domains
  2016-01-22 14:42         ` Andrew Cooper
@ 2016-01-22 14:48           ` Jan Beulich
  2016-01-22 14:56             ` Andrew Cooper
  0 siblings, 1 reply; 123+ messages in thread
From: Jan Beulich @ 2016-01-22 14:48 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 22.01.16 at 15:42, <andrew.cooper3@citrix.com> wrote:
> On 22/01/16 14:33, Jan Beulich wrote:
>>>>> On 22.01.16 at 15:24, <andrew.cooper3@citrix.com> wrote:
>>> On 22/01/16 09:56, Jan Beulich wrote:
>>>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>>>> --- a/xen/arch/x86/cpu/amd.c
>>>>> +++ b/xen/arch/x86/cpu/amd.c
>>>>> @@ -203,7 +203,9 @@ static void __init noinline probe_masking_msrs(void)
>>>>>  void amd_ctxt_switch_levelling(const struct domain *nextd)
>>>>>  {
>>>>>  	struct cpumasks *these_masks = &this_cpu(cpumasks);
>>>>> -	const struct cpumasks *masks = &cpumask_defaults;
>>>>> +	const struct cpumasks *masks =
>>>>> +            (nextd && is_pv_domain(nextd) && nextd->arch.pv_domain.masks)
>>>>> +            ? nextd->arch.pv_domain.masks : &cpumask_defaults;
>>>> Can nextd really ever be NULL here?
>>> Yes, when using this function to set the defaults in the first place
>>> during AP bringup.
>> Ah, I then didn't spot this second use.
>>
>>>>> --- a/xen/arch/x86/domain.c
>>>>> +++ b/xen/arch/x86/domain.c
>>>>> @@ -578,6 +578,12 @@ int arch_domain_create(struct domain *d, unsigned int 
> domcr_flags,
>>>>>              goto fail;
>>>>>          clear_page(d->arch.pv_domain.gdt_ldt_l1tab);
>>>>>  
>>>>> +        d->arch.pv_domain.masks = xmalloc(struct cpumasks);
>>>>> +        if ( !d->arch.pv_domain.masks )
>>>>> +            goto fail;
>>>>> +        memcpy(d->arch.pv_domain.masks, &cpumask_defaults,
>>>>> +               sizeof(*d->arch.pv_domain.masks));
>>>> Structure assignment, to make the thing type safe?
>>>>
>>>> Also there's a change missing to the cleanup code after the "fail"
>>>> label.
>>> What change are you thinking of?  I suppose an xfree() wouldn't go amis,
>>> to prevent a problem for whomever introduces a new failure path, but I
>>> don't see a bug in the code as-is.
>> I don't understand this second sentence. It's the missing addition
>> of a matching xfree() that my comment was about.
> 
> All "goto fails;" are visible in this context.  As the code currently
> stands, there is not a failure path where the allocation isn't freed.

There are numerous "goto fail;" further down in the function afaics.
Are we looking at the same piece of code?

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 27/31] xen/x86: Rework Intel masking/faulting setup
  2016-01-22 14:46         ` Andrew Cooper
@ 2016-01-22 14:53           ` Jan Beulich
  0 siblings, 0 replies; 123+ messages in thread
From: Jan Beulich @ 2016-01-22 14:53 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 22.01.16 at 15:46, <andrew.cooper3@citrix.com> wrote:
> On 22/01/16 14:29, Jan Beulich wrote:
>>>>> On 22.01.16 at 15:09, <andrew.cooper3@citrix.com> wrote:
>>> On 22/01/16 09:40, Jan Beulich wrote:
>>>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>>>> @@ -183,22 +237,13 @@ static void early_init_intel(struct cpuinfo_x86 *c)
>>>>>  	    (boot_cpu_data.x86_mask == 3 || boot_cpu_data.x86_mask == 4))
>>>>>  		paddr_bits = 36;
>>>>>  
>>>>> -	if (c == &boot_cpu_data && c->x86 == 6) {
>>>>> -		if (probe_intel_cpuid_faulting())
>>>>> -			__set_bit(X86_FEATURE_CPUID_FAULTING,
>>>>> -				  c->x86_capability);
>>>>> -	} else if (boot_cpu_has(X86_FEATURE_CPUID_FAULTING)) {
>>>>> -		BUG_ON(!probe_intel_cpuid_faulting());
>>>>> -		__set_bit(X86_FEATURE_CPUID_FAULTING, c->x86_capability);
>>>>> -	}
>>>>> +	if (c == &boot_cpu_data)
>>>>> +		intel_init_levelling();
>>>>> +
>>>>> +	if (test_bit(X86_FEATURE_CPUID_FAULTING, boot_cpu_data.x86_capability))
>>>>> +            __set_bit(X86_FEATURE_CPUID_FAULTING, c->x86_capability);
>>>> So you intentionally delete the validation of CPUID faulting being
>>>> available on APs?
>>> Yes.  All this does is change where Xen crashes, in the case that AP's
>>> have different capabilities to the BSP, and allows more startup code to
>>> move into __init.
>> So where did that Xen crash point move to (since I didn't spot it)?
> 
> set_cpuid_faulting() doesn't use safe MSR accesses, so would crash on
> first use in a mixed setup.

Oh, that's pretty implicit.

> I could extend it to ASSERT(cpu_has_cpuid_faulting) if you would prefer.

If you don't mind, I'd indeed prefer this to be explicit (perhaps
even using BUG_ON() instead of ASSERT()).

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 29/31] x86/pv: Provide custom cpumasks for PV domains
  2016-01-22 14:48           ` Jan Beulich
@ 2016-01-22 14:56             ` Andrew Cooper
  0 siblings, 0 replies; 123+ messages in thread
From: Andrew Cooper @ 2016-01-22 14:56 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 22/01/16 14:48, Jan Beulich wrote:
>>>> On 22.01.16 at 15:42, <andrew.cooper3@citrix.com> wrote:
>> On 22/01/16 14:33, Jan Beulich wrote:
>>>>>> On 22.01.16 at 15:24, <andrew.cooper3@citrix.com> wrote:
>>>> On 22/01/16 09:56, Jan Beulich wrote:
>>>>>>>> On 16.12.15 at 22:24, <andrew.cooper3@citrix.com> wrote:
>>>>>> --- a/xen/arch/x86/cpu/amd.c
>>>>>> +++ b/xen/arch/x86/cpu/amd.c
>>>>>> @@ -203,7 +203,9 @@ static void __init noinline probe_masking_msrs(void)
>>>>>>  void amd_ctxt_switch_levelling(const struct domain *nextd)
>>>>>>  {
>>>>>>  	struct cpumasks *these_masks = &this_cpu(cpumasks);
>>>>>> -	const struct cpumasks *masks = &cpumask_defaults;
>>>>>> +	const struct cpumasks *masks =
>>>>>> +            (nextd && is_pv_domain(nextd) && nextd->arch.pv_domain.masks)
>>>>>> +            ? nextd->arch.pv_domain.masks : &cpumask_defaults;
>>>>> Can nextd really ever be NULL here?
>>>> Yes, when using this function to set the defaults in the first place
>>>> during AP bringup.
>>> Ah, I then didn't spot this second use.
>>>
>>>>>> --- a/xen/arch/x86/domain.c
>>>>>> +++ b/xen/arch/x86/domain.c
>>>>>> @@ -578,6 +578,12 @@ int arch_domain_create(struct domain *d, unsigned int 
>> domcr_flags,
>>>>>>              goto fail;
>>>>>>          clear_page(d->arch.pv_domain.gdt_ldt_l1tab);
>>>>>>  
>>>>>> +        d->arch.pv_domain.masks = xmalloc(struct cpumasks);
>>>>>> +        if ( !d->arch.pv_domain.masks )
>>>>>> +            goto fail;
>>>>>> +        memcpy(d->arch.pv_domain.masks, &cpumask_defaults,
>>>>>> +               sizeof(*d->arch.pv_domain.masks));
>>>>> Structure assignment, to make the thing type safe?
>>>>>
>>>>> Also there's a change missing to the cleanup code after the "fail"
>>>>> label.
>>>> What change are you thinking of?  I suppose an xfree() wouldn't go amis,
>>>> to prevent a problem for whomever introduces a new failure path, but I
>>>> don't see a bug in the code as-is.
>>> I don't understand this second sentence. It's the missing addition
>>> of a matching xfree() that my comment was about.
>> All "goto fails;" are visible in this context.  As the code currently
>> stands, there is not a failure path where the allocation isn't freed.
> There are numerous "goto fail;" further down in the function afaics.
> Are we looking at the same piece of code?

Ah, it has changed between 4.6 and staging, but not sufficiently for
this code to be right on 4.6.  Sorry for the noise.

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 26/31] xen/x86: Rework AMD masking MSR setup
  2016-01-22 14:12           ` Jan Beulich
@ 2016-01-22 17:03             ` Andrew Cooper
  2016-01-25 11:25               ` Jan Beulich
  0 siblings, 1 reply; 123+ messages in thread
From: Andrew Cooper @ 2016-01-22 17:03 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Xen-devel

On 22/01/16 14:12, Jan Beulich wrote:
>
>>>>> And then, how is this supposed to work? You only restore defaults,
>>>>> but never write non-default values. Namely, nextd is an unused
>>>>> function parameter ...
>>>>>
>>>>> Also I guess my comment about adding unused code needs
>>>>> repeating here.
>>>> Future patches build on this, both using the parameter, and not using
>>>> the defaults.
>>>>
>>>> I am also certain that if I did two patches, the first putting in a void
>>>> function, and the second changing it to a pointer, your review would ask
>>>> me to turn it into this.
>>> Well, I realize things will all make sense by the end of the series, but
>>> honestly in some of the cases I'm not sure the split between patches
>>> was well done.
>> If you can suggest a better ordering then I am all ears.
> For example, move all the context switch logic into the patch
> actually invoking the new hook. That still leaves more than
> enough in the AMD and Intel rework patches.

But the context switch logic is used by this patch, which is why it is
introduced here.

It takes the BSP/AP from the boot state into the default levelled state,
by passing NULL as the pointer.  See the final hunk, which modifies
early_init_amd().

~Andrew

^ permalink raw reply	[flat|nested] 123+ messages in thread

* Re: [PATCH RFC 26/31] xen/x86: Rework AMD masking MSR setup
  2016-01-22 17:03             ` Andrew Cooper
@ 2016-01-25 11:25               ` Jan Beulich
  0 siblings, 0 replies; 123+ messages in thread
From: Jan Beulich @ 2016-01-25 11:25 UTC (permalink / raw)
  To: Andrew Cooper; +Cc: Xen-devel

>>> On 22.01.16 at 18:03, <andrew.cooper3@citrix.com> wrote:
> On 22/01/16 14:12, Jan Beulich wrote:
>>
>>>>>> And then, how is this supposed to work? You only restore defaults,
>>>>>> but never write non-default values. Namely, nextd is an unused
>>>>>> function parameter ...
>>>>>>
>>>>>> Also I guess my comment about adding unused code needs
>>>>>> repeating here.
>>>>> Future patches build on this, both using the parameter, and not using
>>>>> the defaults.
>>>>>
>>>>> I am also certain that if I did two patches, the first putting in a void
>>>>> function, and the second changing it to a pointer, your review would ask
>>>>> me to turn it into this.
>>>> Well, I realize things will all make sense by the end of the series, but
>>>> honestly in some of the cases I'm not sure the split between patches
>>>> was well done.
>>> If you can suggest a better ordering then I am all ears.
>> For example, move all the context switch logic into the patch
>> actually invoking the new hook. That still leaves more than
>> enough in the AMD and Intel rework patches.
> 
> But the context switch logic is used by this patch, which is why it is
> introduced here.
> 
> It takes the BSP/AP from the boot state into the default levelled state,
> by passing NULL as the pointer.  See the final hunk, which modifies
> early_init_amd().

Ah, right. Goes back to me not recognizing the dual purpose of that
function (as noted elsewhere in reply to some of your explanations).

Jan

^ permalink raw reply	[flat|nested] 123+ messages in thread

end of thread, other threads:[~2016-01-25 11:25 UTC | newest]

Thread overview: 123+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-16 21:24 [PATCH RFC 00/31] x86: Improvements to cpuid handling for guests Andrew Cooper
2015-12-16 21:24 ` [PATCH RFC 01/31] xen/public: Export featureset information in the public API Andrew Cooper
2015-12-22 16:28   ` Jan Beulich
2015-12-22 16:42     ` Andrew Cooper
2015-12-22 16:59       ` Jan Beulich
2015-12-23 10:05         ` Andrew Cooper
2015-12-23 10:24           ` Jan Beulich
2015-12-23 11:26             ` Andrew Cooper
2016-01-06  7:43               ` Jan Beulich
2015-12-16 21:24 ` [PATCH RFC 02/31] tools/libxc: Use public/featureset.h for cpuid policy generation Andrew Cooper
2015-12-22 16:29   ` Jan Beulich
2016-01-05 14:13     ` Ian Campbell
2016-01-05 14:17       ` Andrew Cooper
2016-01-05 14:18         ` Ian Campbell
2016-01-05 14:23           ` Andrew Cooper
2016-01-05 15:02             ` Ian Campbell
2016-01-05 15:42               ` Andrew Cooper
2016-01-05 16:09                 ` Ian Campbell
2015-12-16 21:24 ` [PATCH RFC 03/31] xen/x86: Store antifeatures inverted in a featureset Andrew Cooper
2015-12-22 16:32   ` Jan Beulich
2015-12-22 17:03     ` Andrew Cooper
2016-01-05 14:19       ` Ian Campbell
2016-01-05 14:24         ` Andrew Cooper
2015-12-16 21:24 ` [PATCH RFC 04/31] xen/x86: Mask out unknown features from Xen's capabilities Andrew Cooper
2015-12-22 16:42   ` Jan Beulich
2015-12-22 17:01     ` Andrew Cooper
2015-12-16 21:24 ` [PATCH RFC 05/31] xen/x86: Collect more CPUID feature words Andrew Cooper
2015-12-22 16:46   ` Jan Beulich
2015-12-22 17:17     ` Andrew Cooper
2015-12-16 21:24 ` [PATCH RFC 06/31] xen/x86: Infrastructure to calculate guest featuresets Andrew Cooper
2015-12-22 16:50   ` Jan Beulich
2015-12-16 21:24 ` [PATCH RFC 07/31] xen/x86: Export host featureset via SYSCTL Andrew Cooper
2015-12-22 16:57   ` Jan Beulich
2015-12-16 21:24 ` [PATCH RFC 08/31] tools/stubs: Expose host featureset to userspace Andrew Cooper
2016-01-05 15:36   ` Ian Campbell
2016-01-05 15:59     ` Andrew Cooper
2016-01-05 16:09       ` Ian Campbell
2016-01-05 16:19         ` Andrew Cooper
2016-01-05 16:38           ` Ian Campbell
2015-12-16 21:24 ` [PATCH RFC 09/31] xen/x86: Calculate PV featureset Andrew Cooper
2015-12-22 17:07   ` Jan Beulich
2015-12-22 17:13     ` Andrew Cooper
2015-12-22 17:18       ` Jan Beulich
2015-12-16 21:24 ` [PATCH RFC 10/31] xen/x86: Calculate HVM featureset Andrew Cooper
2015-12-22 17:11   ` Jan Beulich
2015-12-22 17:21     ` Andrew Cooper
2015-12-16 21:24 ` [PATCH RFC 11/31] xen/x86: Calculate Raw featureset Andrew Cooper
2015-12-22 17:14   ` Jan Beulich
2015-12-22 17:27     ` Andrew Cooper
2015-12-16 21:24 ` [PATCH RFC 12/31] tools: Utility for dealing with featuresets Andrew Cooper
2016-01-05 15:17   ` Ian Campbell
2016-01-05 16:14     ` Andrew Cooper
2016-01-05 16:34       ` Ian Campbell
2016-01-05 17:13         ` Andrew Cooper
2016-01-05 17:37           ` Ian Campbell
2016-01-05 18:04             ` Andrew Cooper
2016-01-06 10:38               ` Ian Campbell
2016-01-06 10:40   ` Ian Campbell
2016-01-06 10:42     ` Ian Campbell
2015-12-16 21:24 ` [PATCH RFC 13/31] tools/libxc: Wire a featureset through to cpuid policy logic Andrew Cooper
2016-01-05 15:42   ` Ian Campbell
2016-01-05 16:20     ` Andrew Cooper
2015-12-16 21:24 ` [PATCH RFC 14/31] tools/libxc: Use featureset rather than guesswork Andrew Cooper
2016-01-05 15:54   ` Ian Campbell
2016-01-05 16:22     ` Andrew Cooper
2015-12-16 21:24 ` [PATCH RFC 15/31] x86: Generate deep dependencies of x86 features Andrew Cooper
2016-01-05 16:03   ` Ian Campbell
2016-01-05 16:42     ` Andrew Cooper
2016-01-05 16:54       ` Ian Campbell
2016-01-05 17:09         ` Andrew Cooper
2016-01-05 17:19           ` Ian Campbell
2015-12-16 21:24 ` [PATCH RFC 16/31] x86: Automatically generate known_features Andrew Cooper
2015-12-16 21:24 ` [PATCH RFC 17/31] xen/x86: Clear dependent features when clearing a cpu cap Andrew Cooper
2015-12-16 21:24 ` [PATCH RFC 18/31] xen/x86: Improve disabling of features which have dependencies Andrew Cooper
2016-01-21 16:48   ` Jan Beulich
2015-12-16 21:24 ` [PATCH RFC 19/31] tools/libxc: Sanitise guest featuresets Andrew Cooper
2016-01-05 16:05   ` Ian Campbell
2015-12-16 21:24 ` [PATCH RFC 20/31] x86: Improvements to in-hypervisor cpuid sanity checks Andrew Cooper
2016-01-21 17:02   ` Jan Beulich
2016-01-21 17:21     ` Andrew Cooper
2016-01-21 18:15       ` Andrew Cooper
2016-01-22  7:47         ` Jan Beulich
2016-01-22  7:45       ` Jan Beulich
2015-12-16 21:24 ` [PATCH RFC 21/31] x86/domctl: Break out logic to update domain state from cpuid information Andrew Cooper
2016-01-21 17:05   ` Jan Beulich
2016-01-21 17:08     ` Andrew Cooper
2015-12-16 21:24 ` [PATCH RFC 22/31] x86/cpu: Move set_cpumask() calls into c_early_init() Andrew Cooper
2016-01-21 17:08   ` Jan Beulich
2015-12-16 21:24 ` [PATCH RFC 23/31] xen/x86: Export cpuid levelling capabilities via SYSCTL Andrew Cooper
2016-01-21 17:23   ` Jan Beulich
2015-12-16 21:24 ` [PATCH RFC 24/31] tools/stubs: Expose host levelling capabilities to userspace Andrew Cooper
2015-12-16 21:24 ` [PATCH RFC 25/31] xen/x86: Common infrastructure for levelling context switching Andrew Cooper
2016-01-22  8:56   ` Jan Beulich
2016-01-22 10:05     ` Andrew Cooper
2015-12-16 21:24 ` [PATCH RFC 26/31] xen/x86: Rework AMD masking MSR setup Andrew Cooper
2016-01-22  9:27   ` Jan Beulich
2016-01-22 11:01     ` Andrew Cooper
2016-01-22 11:13       ` Jan Beulich
2016-01-22 13:59         ` Andrew Cooper
2016-01-22 14:12           ` Jan Beulich
2016-01-22 17:03             ` Andrew Cooper
2016-01-25 11:25               ` Jan Beulich
2015-12-16 21:24 ` [PATCH RFC 27/31] xen/x86: Rework Intel masking/faulting setup Andrew Cooper
2016-01-22  9:40   ` Jan Beulich
2016-01-22 14:09     ` Andrew Cooper
2016-01-22 14:29       ` Jan Beulich
2016-01-22 14:46         ` Andrew Cooper
2016-01-22 14:53           ` Jan Beulich
2015-12-16 21:24 ` [PATCH RFC 28/31] xen/x86: Context switch all levelling state in context_switch() Andrew Cooper
2016-01-22  9:52   ` Jan Beulich
2016-01-22 14:19     ` Andrew Cooper
2016-01-22 14:31       ` Jan Beulich
2016-01-22 14:39         ` Andrew Cooper
2015-12-16 21:24 ` [PATCH RFC 29/31] x86/pv: Provide custom cpumasks for PV domains Andrew Cooper
2016-01-22  9:56   ` Jan Beulich
2016-01-22 14:24     ` Andrew Cooper
2016-01-22 14:33       ` Jan Beulich
2016-01-22 14:42         ` Andrew Cooper
2016-01-22 14:48           ` Jan Beulich
2016-01-22 14:56             ` Andrew Cooper
2015-12-16 21:24 ` [PATCH RFC 30/31] x86/domctl: Update PV domain cpumasks when setting cpuid policy Andrew Cooper
2016-01-22 10:02   ` Jan Beulich
2015-12-16 21:24 ` [PATCH RFC 31/31] tools/libxc: Calculate xstate cpuid leaf from guest information Andrew Cooper

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.