Re: [Xen-devel] [PATCH v2] x86: invpcid support

2018-03-05 Thread Jan Beulich
>>> On 02.03.18 at 18:01,  wrote:
> On 02/03/18 16:47, Jan Beulich wrote:
> On 02.03.18 at 17:23,  wrote:
>>> +static inline void invpcid(unsigned int pcid, unsigned long addr,
>>> +   unsigned int type)
>>> +{
>>> +struct {
>>> +uint64_t pcid:12;
>>> +uint64_t reserved:52;
>>> +uint64_t addr;
>>> +} desc = { .pcid = pcid, .addr = addr };
>>> +
>>> +asm volatile (
>>> +#ifdef HAVE_AS_INVPCID
>>> +  "invpcid %[desc], %q[type]"
>>> +  : /* No output */
>>> +  : [desc] "m" (desc), [type] "r" (type)
>>> +#else
>>> +  INVPCID_OPCODE MODRM_ECX_01
>>> +  : /* No output */
>>> +  : "a" (type), "c" (&desc)
>>> +#endif
>>> +  : "memory" );
>> I can see why you need the memory clobber in the #else case
>> (albeit even there it could be avoided by also properly specifying
>> the input), but what is this good for in the #if case?
> 
> This is a tlb flush operation.  I don't think anything good will come
> from having other operations reordered around it.

Well, the question is whose TLB it is that is being flushed. If we
invalidate Xen mappings this way, then yes. But there may be
cases down the road where the construct is used to only flush
guest mappings, in which case the barrier seems pointless. But
anyway - not a big deal for now. It's just that I recall that we
had (or perhaps still have) quite a few too many such barriers.

Jan


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] [PATCH v2] x86: invpcid support

2018-03-02 Thread Wei Liu
On Fri, Mar 02, 2018 at 09:47:45AM -0700, Jan Beulich wrote:
> >>> On 02.03.18 at 17:23,  wrote:
> > +static inline void invpcid(unsigned int pcid, unsigned long addr,
> > +   unsigned int type)
> > +{
> > +struct {
> > +uint64_t pcid:12;
> > +uint64_t reserved:52;
> > +uint64_t addr;
> > +} desc = { .pcid = pcid, .addr = addr };
> > +
> > +asm volatile (
> > +#ifdef HAVE_AS_INVPCID
> > +  "invpcid %[desc], %q[type]"
> > +  : /* No output */
> > +  : [desc] "m" (desc), [type] "r" (type)
> > +#else
> > +  INVPCID_OPCODE MODRM_ECX_01
> > +  : /* No output */
> > +  : "a" (type), "c" (&desc)
> > +#endif
> > +  : "memory" );
> 
> I can see why you need the memory clobber in the #else case
> (albeit even there it could be avoided by also properly specifying
> the input), but what is this good for in the #if case?

It is the same as why writing to CR3 requires a memory clobber. It is
flushing TLB.

Wei.

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] [PATCH v2] x86: invpcid support

2018-03-02 Thread Andrew Cooper
On 02/03/18 16:47, Jan Beulich wrote:
 On 02.03.18 at 17:23,  wrote:
>> +static inline void invpcid(unsigned int pcid, unsigned long addr,
>> +   unsigned int type)
>> +{
>> +struct {
>> +uint64_t pcid:12;
>> +uint64_t reserved:52;
>> +uint64_t addr;
>> +} desc = { .pcid = pcid, .addr = addr };
>> +
>> +asm volatile (
>> +#ifdef HAVE_AS_INVPCID
>> +  "invpcid %[desc], %q[type]"
>> +  : /* No output */
>> +  : [desc] "m" (desc), [type] "r" (type)
>> +#else
>> +  INVPCID_OPCODE MODRM_ECX_01
>> +  : /* No output */
>> +  : "a" (type), "c" (&desc)
>> +#endif
>> +  : "memory" );
> I can see why you need the memory clobber in the #else case
> (albeit even there it could be avoided by also properly specifying
> the input), but what is this good for in the #if case?

This is a tlb flush operation.  I don't think anything good will come
from having other operations reordered around it.

~Andrew

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] [PATCH v2] x86: invpcid support

2018-03-02 Thread Jan Beulich
>>> On 02.03.18 at 17:23,  wrote:
> +static inline void invpcid(unsigned int pcid, unsigned long addr,
> +   unsigned int type)
> +{
> +struct {
> +uint64_t pcid:12;
> +uint64_t reserved:52;
> +uint64_t addr;
> +} desc = { .pcid = pcid, .addr = addr };
> +
> +asm volatile (
> +#ifdef HAVE_AS_INVPCID
> +  "invpcid %[desc], %q[type]"
> +  : /* No output */
> +  : [desc] "m" (desc), [type] "r" (type)
> +#else
> +  INVPCID_OPCODE MODRM_ECX_01
> +  : /* No output */
> +  : "a" (type), "c" (&desc)
> +#endif
> +  : "memory" );

I can see why you need the memory clobber in the #else case
(albeit even there it could be avoided by also properly specifying
the input), but what is this good for in the #if case?

Jan


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

Re: [Xen-devel] [PATCH v2] x86: invpcid support

2018-03-02 Thread Andrew Cooper
On 02/03/18 16:23, Wei Liu wrote:
> Provide the functions needed for different modes. Add cpu_has_invpcid.
>
> Signed-off-by: Wei Liu 
> Reviewed-by: Juergen Gross 

Reviewed-by: Andrew Cooper 

___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel

[Xen-devel] [PATCH v2] x86: invpcid support

2018-03-02 Thread Wei Liu
Provide the functions needed for different modes. Add cpu_has_invpcid.

Signed-off-by: Wei Liu 
Reviewed-by: Juergen Gross 
---
Cc: Jan Beulich 
Cc: Andrew Cooper 
Cc: Juergen Gross 
---
 xen/arch/x86/Rules.mk|  1 +
 xen/include/asm-x86/cpufeature.h |  1 +
 xen/include/asm-x86/invpcid.h| 70 
 3 files changed, 72 insertions(+)
 create mode 100644 xen/include/asm-x86/invpcid.h

diff --git a/xen/arch/x86/Rules.mk b/xen/arch/x86/Rules.mk
index 9897deaab9..acec5ce92a 100644
--- a/xen/arch/x86/Rules.mk
+++ b/xen/arch/x86/Rules.mk
@@ -23,6 +23,7 @@ $(call as-option-add,CFLAGS,CC,"rdseed 
%eax",-DHAVE_GAS_RDSEED)
 $(call as-option-add,CFLAGS,CC,".equ \"x\"$$(comma)1", \
  -U__OBJECT_LABEL__ -DHAVE_GAS_QUOTED_SYM \
  '-D__OBJECT_LABEL__=$(subst $(BASEDIR)/,,$(CURDIR))/$$@')
+$(call as-option-add,CFLAGS,CC,"invpcid (%rax)$$(comma)%rax",-DHAVE_AS_INVPCID)
 
 CFLAGS += -mno-red-zone -fpic -fno-asynchronous-unwind-tables
 
diff --git a/xen/include/asm-x86/cpufeature.h b/xen/include/asm-x86/cpufeature.h
index 55b696ed07..db8072279d 100644
--- a/xen/include/asm-x86/cpufeature.h
+++ b/xen/include/asm-x86/cpufeature.h
@@ -93,6 +93,7 @@
 #define cpu_has_avx2boot_cpu_has(X86_FEATURE_AVX2)
 #define cpu_has_smepboot_cpu_has(X86_FEATURE_SMEP)
 #define cpu_has_bmi2boot_cpu_has(X86_FEATURE_BMI2)
+#define cpu_has_invpcid boot_cpu_has(X86_FEATURE_INVPCID)
 #define cpu_has_rtm boot_cpu_has(X86_FEATURE_RTM)
 #define cpu_has_fpu_sel (!boot_cpu_has(X86_FEATURE_NO_FPU_SEL))
 #define cpu_has_mpx boot_cpu_has(X86_FEATURE_MPX)
diff --git a/xen/include/asm-x86/invpcid.h b/xen/include/asm-x86/invpcid.h
new file mode 100644
index 00..b46624a865
--- /dev/null
+++ b/xen/include/asm-x86/invpcid.h
@@ -0,0 +1,70 @@
+#ifndef _ASM_X86_INVPCID_H_
+#define _ASM_X86_INVPCID_H_
+
+#include 
+
+#define INVPCID_TYPE_INDIV_ADDR  0
+#define INVPCID_TYPE_SINGLE_CTXT 1
+#define INVPCID_TYPE_ALL_INCL_GLOBAL 2
+#define INVPCID_TYPE_ALL_NON_GLOBAL  3
+
+#define INVPCID_OPCODE ".byte 0x66, 0x0f, 0x38, 0x82\n"
+#define MODRM_ECX_01   ".byte 0x01\n"
+
+static inline void invpcid(unsigned int pcid, unsigned long addr,
+   unsigned int type)
+{
+struct {
+uint64_t pcid:12;
+uint64_t reserved:52;
+uint64_t addr;
+} desc = { .pcid = pcid, .addr = addr };
+
+asm volatile (
+#ifdef HAVE_AS_INVPCID
+  "invpcid %[desc], %q[type]"
+  : /* No output */
+  : [desc] "m" (desc), [type] "r" (type)
+#else
+  INVPCID_OPCODE MODRM_ECX_01
+  : /* No output */
+  : "a" (type), "c" (&desc)
+#endif
+  : "memory" );
+}
+
+/* Flush all mappings for a given PCID and addr, not including globals */
+static inline void invpcid_flush_one(unsigned int pcid, unsigned long addr)
+{
+invpcid(pcid, addr, INVPCID_TYPE_INDIV_ADDR);
+}
+
+/* Flush all mappings for a given PCID, not including globals */
+static inline void invpcid_flush_single_context(unsigned int pcid)
+{
+invpcid(pcid, 0, INVPCID_TYPE_SINGLE_CTXT);
+}
+
+/* Flush all mappings, including globals, for all PCIDs */
+static inline void invpcid_flush_all(void)
+{
+invpcid(0, 0, INVPCID_TYPE_ALL_INCL_GLOBAL);
+}
+
+/* Flush all mappings for all PCIDs, excluding globals */
+static inline void invpcid_flush_all_nonglobals(void)
+{
+invpcid(0, 0, INVPCID_TYPE_ALL_NON_GLOBAL);
+}
+
+#endif /* _ASM_X86_INVPCID_H_ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
-- 
2.11.0


___
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel