[Xen-devel] [PATCH 6/6] x86: Pass through intel processor trace MSRs

2017-10-22 Thread Luwei Kang
This patch pass through Intel processor trace MSRs
to guest.

Signed-off-by: Luwei Kang 
---
 xen/arch/x86/cpu/intel_pt.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/xen/arch/x86/cpu/intel_pt.c b/xen/arch/x86/cpu/intel_pt.c
index 411b922..8e83b87 100644
--- a/xen/arch/x86/cpu/intel_pt.c
+++ b/xen/arch/x86/cpu/intel_pt.c
@@ -82,6 +82,7 @@ void pt_vcpu_init(struct vcpu *v)
 {
 struct pt_desc *pt = &v->arch.hvm_vmx.pt_desc;
 unsigned int eax, ebx, ecx, edx;
+int i;
 
 memset(pt, 0, sizeof(struct pt_desc));
 pt->intel_pt_enabled = false;
@@ -102,5 +103,12 @@ void pt_vcpu_init(struct vcpu *v)
 
 vmx_vmcs_enter(v);
 __vmwrite(GUEST_IA32_RTIT_CTL, 0);
+vmx_clear_msr_intercept(v, MSR_IA32_RTIT_CTL, VMX_MSR_RW);
+vmx_clear_msr_intercept(v, MSR_IA32_RTIT_STATUS, VMX_MSR_RW);
+vmx_clear_msr_intercept(v, MSR_IA32_RTIT_OUTPUT_BASE, VMX_MSR_RW);
+vmx_clear_msr_intercept(v, MSR_IA32_RTIT_OUTPUT_MASK_PTRS, VMX_MSR_RW);
+vmx_clear_msr_intercept(v, MSR_IA32_RTIT_CR3_MATCH, VMX_MSR_RW);
+for ( i = 0; i < pt->addr_num; i++ )
+vmx_clear_msr_intercept(v, MSR_IA32_RTIT_ADDR0_A + i, VMX_MSR_RW);
 vmx_vmcs_exit(v);
 }
-- 
1.8.3.1


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


[Xen-devel] [PATCH 2/6] x86: configure vmcs for Intel processor trace virtualization

2017-10-22 Thread Luwei Kang
This patch configure VMCS to make Intel PT output address can be
treat as guest physical address and translated by EPT when
intel_pt option is true.
There have some constraint condition on VMCS configuration,
otherwise will cause VM entry failed.

1. If the “Guest PT uses Guest Physical Addresses” execution
   control is 1, the “Clear IA32_RTIT_CTL on exit” exit
   control and the “Load IA32_RTIT_CTL on entry” entry
   control must also be 1.

2. If the “Guest PT uses Guest Physical Addresses” execution
   control is 1, the "enable EPT" execution control must
   also be 1.

Signed-off-by: Luwei Kang 
---
 xen/arch/x86/hvm/vmx/vmcs.c| 36 +++-
 xen/include/asm-x86/hvm/vmx/vmcs.h |  7 +++
 2 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c
index f62fe7e..8cd57b5 100644
--- a/xen/arch/x86/hvm/vmx/vmcs.c
+++ b/xen/arch/x86/hvm/vmx/vmcs.c
@@ -40,6 +40,7 @@
 #include 
 #include 
 #include 
+#include 
 
 static bool_t __read_mostly opt_vpid_enabled = 1;
 boolean_param("vpid", opt_vpid_enabled);
@@ -242,6 +243,9 @@ static int vmx_init_vmcs_config(void)
 rdmsrl(MSR_IA32_VMX_MISC, _vmx_misc_cap);
 if ( _vmx_misc_cap & VMX_MISC_VMWRITE_ALL )
 opt |= SECONDARY_EXEC_ENABLE_VMCS_SHADOWING;
+if ( _vmx_misc_cap & VMX_MISC_PT_ENABLE )
+opt |= SECONDARY_EXEC_PT_USE_GPA |
+   SECONDARY_EXEC_CONCEAL_PT_PIP;
 if ( opt_vpid_enabled )
 opt |= SECONDARY_EXEC_ENABLE_VPID;
 if ( opt_unrestricted_guest_enabled )
@@ -343,7 +347,8 @@ static int vmx_init_vmcs_config(void)
 
 min = VM_EXIT_ACK_INTR_ON_EXIT;
 opt = VM_EXIT_SAVE_GUEST_PAT | VM_EXIT_LOAD_HOST_PAT |
-  VM_EXIT_CLEAR_BNDCFGS;
+  VM_EXIT_CLEAR_BNDCFGS | VM_EXIT_CONCEAL_PT_PIP |
+  VM_EXIT_CLEAR_IA32_RTIT_CTL;
 min |= VM_EXIT_IA32E_MODE;
 _vmx_vmexit_control = adjust_vmx_controls(
 "VMExit Control", min, opt, MSR_IA32_VMX_EXIT_CTLS, &mismatch);
@@ -383,13 +388,28 @@ static int vmx_init_vmcs_config(void)
 _vmx_secondary_exec_control &= ~SECONDARY_EXEC_ENABLE_VIRT_EXCEPTIONS;
 
 min = 0;
-opt = VM_ENTRY_LOAD_GUEST_PAT | VM_ENTRY_LOAD_BNDCFGS;
+opt = VM_ENTRY_LOAD_GUEST_PAT | VM_ENTRY_LOAD_BNDCFGS |
+  VM_ENTRY_CONCEAL_PT_PIP | VM_ENTRY_LOAD_IA32_RTIT_CTL;
 _vmx_vmentry_control = adjust_vmx_controls(
 "VMEntry Control", min, opt, MSR_IA32_VMX_ENTRY_CTLS, &mismatch);
 
 if ( mismatch )
 return -EINVAL;
 
+if ( !(_vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_EPT) ||
+ !(_vmx_secondary_exec_control & SECONDARY_EXEC_PT_USE_GPA) ||
+ !(_vmx_vmexit_control & VM_EXIT_CLEAR_IA32_RTIT_CTL) ||
+ !(_vmx_vmentry_control & VM_ENTRY_LOAD_IA32_RTIT_CTL) )
+{
+_vmx_secondary_exec_control &= ~(SECONDARY_EXEC_PT_USE_GPA |
+ SECONDARY_EXEC_CONCEAL_PT_PIP);
+_vmx_vmexit_control &= ~(VM_EXIT_CONCEAL_PT_PIP |
+ VM_EXIT_CLEAR_IA32_RTIT_CTL);
+_vmx_vmentry_control &= ~(VM_ENTRY_CONCEAL_PT_PIP |
+  VM_ENTRY_LOAD_IA32_RTIT_CTL);
+opt_intel_pt = 0;
+}
+
 if ( !vmx_pin_based_exec_control )
 {
 /* First time through. */
@@ -1032,10 +1052,16 @@ static int construct_vmcs(struct vcpu *v)
 v->arch.hvm_vmx.secondary_exec_control &= 
 ~(SECONDARY_EXEC_ENABLE_EPT | 
   SECONDARY_EXEC_UNRESTRICTED_GUEST |
-  SECONDARY_EXEC_ENABLE_INVPCID);
+  SECONDARY_EXEC_ENABLE_INVPCID |
+  SECONDARY_EXEC_PT_USE_GPA |
+  SECONDARY_EXEC_CONCEAL_PT_PIP);
 vmexit_ctl &= ~(VM_EXIT_SAVE_GUEST_PAT |
-VM_EXIT_LOAD_HOST_PAT);
-vmentry_ctl &= ~VM_ENTRY_LOAD_GUEST_PAT;
+VM_EXIT_LOAD_HOST_PAT |
+VM_EXIT_CONCEAL_PT_PIP |
+VM_EXIT_CLEAR_IA32_RTIT_CTL);
+vmentry_ctl &= ~(VM_ENTRY_LOAD_GUEST_PAT |
+ VM_ENTRY_CONCEAL_PT_PIP |
+ VM_ENTRY_LOAD_IA32_RTIT_CTL);
 }
 
 /* Disable Virtualize x2APIC mode by default. */
diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h 
b/xen/include/asm-x86/hvm/vmx/vmcs.h
index 8fb9e3c..bd8a128 100644
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -220,6 +220,8 @@ extern u32 vmx_pin_based_exec_control;
 #define VM_EXIT_LOAD_HOST_EFER  0x0020
 #define VM_EXIT_SAVE_PREEMPT_TIMER  0x0040
 #define VM_EXIT_CLEAR_BNDCFGS   0x0080
+#define VM_EXIT_CONCEAL_PT_PIP  0x0100
+#define VM_EXIT_CLEAR_IA32_RTIT_CTL 0x0200
 extern u32 vmx_vmexit_control;
 
 #define VM_ENTRY_IA32E_MODE 0x

[Xen-devel] [PATCH 3/6] x86: add intel proecessor trace support for cpuid

2017-10-22 Thread Luwei Kang
This patch add Intel processor trace support
for cpuid handling.

Signed-off-by: Luwei Kang 
---
 tools/libxc/xc_cpuid_x86.c  | 12 ++--
 xen/arch/x86/cpuid.c| 22 ++
 xen/arch/x86/domctl.c   |  4 
 xen/include/asm-x86/cpufeature.h|  1 +
 xen/include/asm-x86/cpuid.h | 12 +++-
 xen/include/public/arch-x86/cpufeatureset.h |  1 +
 6 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
index d890935..0e0575c 100644
--- a/tools/libxc/xc_cpuid_x86.c
+++ b/tools/libxc/xc_cpuid_x86.c
@@ -38,7 +38,7 @@ enum {
 #define clear_feature(idx, dst) ((dst) &= ~bitmaskof(idx))
 #define set_feature(idx, dst)   ((dst) |=  bitmaskof(idx))
 
-#define DEF_MAX_BASE 0x000du
+#define DEF_MAX_BASE 0x0014u
 #define DEF_MAX_INTELEXT  0x8008u
 #define DEF_MAX_AMDEXT0x801cu
 
@@ -471,6 +471,7 @@ static void xc_cpuid_hvm_policy(xc_interface *xch,
 case 0x0002: /* Intel cache info (dumped by AMD policy) */
 case 0x0004: /* Intel cache info (dumped by AMD policy) */
 case 0x000a: /* Architectural Performance Monitor Features */
+case 0x0014: /* Intel Processor Trace Features */
 case 0x8002: /* Processor name string */
 case 0x8003: /* ... continued */
 case 0x8004: /* ... continued */
@@ -757,12 +758,19 @@ int xc_cpuid_apply_policy(xc_interface *xch, domid_t 
domid,
 continue;
 }
 
+if ( input[0] == 0x14 )
+{
+input[1]++;
+if ( input[1] == 1 )
+continue;
+}
+
 input[0]++;
 if ( !(input[0] & 0x8000u) && (input[0] > base_max ) )
 input[0] = 0x8000u;
 
 input[1] = XEN_CPUID_INPUT_UNUSED;
-if ( (input[0] == 4) || (input[0] == 7) )
+if ( (input[0] == 4) || (input[0] == 7) || (input[0] == 0x14) )
 input[1] = 0;
 else if ( input[0] == 0xd )
 input[1] = 1; /* Xen automatically calculates almost everything. */
diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c
index 5ee82d3..c3d56fd 100644
--- a/xen/arch/x86/cpuid.c
+++ b/xen/arch/x86/cpuid.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 
 const uint32_t known_features[] = INIT_KNOWN_FEATURES;
 const uint32_t special_features[] = INIT_SPECIAL_FEATURES;
@@ -487,7 +488,19 @@ void recalculate_cpuid_policy(struct domain *d)
 __clear_bit(X86_FEATURE_VMX, max_fs);
 __clear_bit(X86_FEATURE_SVM, max_fs);
 }
+
+/*
+ * Hide Intel Processor trace feature when hardware not support
+ * PT-VMX or intel_pt option is disabled.
+ */
+if ( !opt_intel_pt )
+{
+__clear_bit(X86_FEATURE_INTEL_PT, max_fs);
+zero_leaves(p->intel_pt.raw, 0, ARRAY_SIZE(p->intel_pt.raw) - 1);
+}
 }
+else
+zero_leaves(p->intel_pt.raw, 0, ARRAY_SIZE(p->intel_pt.raw) - 1);
 
 /*
  * Allow the toolstack to set HTT, X2APIC and CMP_LEGACY.  These bits
@@ -634,6 +647,15 @@ void guest_cpuid(const struct vcpu *v, uint32_t leaf,
 *res = p->feat.raw[subleaf];
 break;
 
+case 0x14:
+ASSERT(p->intel_pt.max_subleaf < ARRAY_SIZE(p->intel_pt.raw));
+if ( subleaf > min_t(uint32_t, p->intel_pt.max_subleaf,
+ ARRAY_SIZE(p->intel_pt.raw) - 1) )
+return;
+
+*res = p->intel_pt.raw[subleaf];
+break;
+
 case XSTATE_CPUID:
 if ( !p->basic.xsave || subleaf >= ARRAY_SIZE(p->xstate.raw) )
 return;
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index 1b208f9..405b31e 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -100,6 +100,10 @@ static int update_domain_cpuid_info(struct domain *d,
 p->feat.raw[ctl->input[1]] = leaf;
 break;
 
+case 0x14:
+p->intel_pt.raw[ctl->input[1]] = leaf;
+break;
+
 case XSTATE_CPUID:
 p->xstate.raw[ctl->input[1]] = leaf;
 break;
diff --git a/xen/include/asm-x86/cpufeature.h b/xen/include/asm-x86/cpufeature.h
index 84cc51d..8956667 100644
--- a/xen/include/asm-x86/cpufeature.h
+++ b/xen/include/asm-x86/cpufeature.h
@@ -95,6 +95,7 @@
 #define cpu_has_mpx boot_cpu_has(X86_FEATURE_MPX)
 #define cpu_has_rdseed  boot_cpu_has(X86_FEATURE_RDSEED)
 #define cpu_has_smapboot_cpu_has(X86_FEATURE_SMAP)
+#define cpu_has_intel_ptboot_cpu_has(X86_FEATURE_INTEL_PT)
 #define cpu_has_sha boot_cpu_has(X86_FEATURE_SHA)
 
 /* CPUID level 0x8007.edx */
diff --git a/xen/include/asm-x86/cpuid.h b/xen/include/asm-x86/cpuid.h
index d2dd841..

[Xen-devel] [PATCH 4/6] x86: add intel processor trace context

2017-10-22 Thread Luwei Kang
This patch add Intel processor trace context
date structure for guest.

Signed-off-by: Luwei Kang 
---
 xen/include/asm-x86/hvm/vmx/vmcs.h |  3 +++
 xen/include/asm-x86/intel_pt.h | 17 +
 xen/include/asm-x86/msr-index.h| 16 
 3 files changed, 36 insertions(+)

diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h 
b/xen/include/asm-x86/hvm/vmx/vmcs.h
index bd8a128..33ec3e6 100644
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -20,6 +20,7 @@
 
 #include 
 #include 
+#include 
 
 extern void vmcs_dump_vcpu(struct vcpu *v);
 extern void setup_vmcs_dump(void);
@@ -171,6 +172,8 @@ struct arch_vmx_struct {
  * pCPU and wakeup the related vCPU.
  */
 struct pi_blocking_vcpu pi_blocking;
+
+struct pt_desc   pt_desc;
 };
 
 int vmx_create_vmcs(struct vcpu *v);
diff --git a/xen/include/asm-x86/intel_pt.h b/xen/include/asm-x86/intel_pt.h
index 3b3a047..78e3a37 100644
--- a/xen/include/asm-x86/intel_pt.h
+++ b/xen/include/asm-x86/intel_pt.h
@@ -21,6 +21,23 @@
 #ifndef __ASM_X86_HVM_INTEL_PT_H_
 #define __ASM_X86_HVM_INTEL_PT_H_
 
+#include 
+
+struct pt_ctx {
+u64 ctl;
+u64 status;
+u64 output_base;
+u64 output_mask_ptrs;
+u64 cr3_match;
+u64 addr[NUM_MSR_IA32_RTIT_ADDR];
+};
+
+struct pt_desc {
+bool intel_pt_enabled;
+unsigned int addr_num;
+struct pt_ctx guest_pt_ctx;
+};
+
 extern bool_t opt_intel_pt;
 
 #endif /* __ASM_X86_HVM_INTEL_PT_H_ */
diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h
index b99c623..d160d44 100644
--- a/xen/include/asm-x86/msr-index.h
+++ b/xen/include/asm-x86/msr-index.h
@@ -528,4 +528,20 @@
 #define MSR_PKGC9_IRTL 0x0634
 #define MSR_PKGC10_IRTL0x0635
 
+/* Intel PT MSRs */
+#define MSR_IA32_RTIT_CTL  0x0570
+#define MSR_IA32_RTIT_STATUS   0x0571
+#define MSR_IA32_RTIT_CR3_MATCH0x0572
+#define MSR_IA32_RTIT_OUTPUT_BASE  0x0560
+#define MSR_IA32_RTIT_OUTPUT_MASK_PTRS 0x0561
+#define MSR_IA32_RTIT_ADDR0_A  0x0580
+#define MSR_IA32_RTIT_ADDR0_B  0x0581
+#define MSR_IA32_RTIT_ADDR1_A  0x0582
+#define MSR_IA32_RTIT_ADDR1_B  0x0583
+#define MSR_IA32_RTIT_ADDR2_A  0x0584
+#define MSR_IA32_RTIT_ADDR2_B  0x0585
+#define MSR_IA32_RTIT_ADDR3_A  0x0586
+#define MSR_IA32_RTIT_ADDR3_B  0x0587
+#define NUM_MSR_IA32_RTIT_ADDR 8
+
 #endif /* __ASM_MSR_INDEX_H */
-- 
1.8.3.1


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


[Xen-devel] [PATCH 5/6] x86: implement intel processor trace context switch

2017-10-22 Thread Luwei Kang
This patch implement Intel proecessor trace context switch.

Signed-off-by: Luwei Kang 
---
 xen/arch/x86/cpu/intel_pt.c| 79 ++
 xen/arch/x86/hvm/vmx/vmx.c |  4 ++
 xen/include/asm-x86/hvm/vmx/vmcs.h |  2 +
 xen/include/asm-x86/intel_pt.h |  4 ++
 4 files changed, 89 insertions(+)

diff --git a/xen/arch/x86/cpu/intel_pt.c b/xen/arch/x86/cpu/intel_pt.c
index be06d55..411b922 100644
--- a/xen/arch/x86/cpu/intel_pt.c
+++ b/xen/arch/x86/cpu/intel_pt.c
@@ -21,7 +21,86 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 /* intel_pt: Flag to enable Intel Processor Trace (default on). */
 bool_t __read_mostly opt_intel_pt = 1;
 boolean_param("intel_pt", opt_intel_pt);
+
+static inline void pt_load_msr(struct pt_ctx *ctx, u32 addr_num)
+{
+u32 i;
+wrmsrl(MSR_IA32_RTIT_STATUS, ctx->status);
+wrmsrl(MSR_IA32_RTIT_OUTPUT_BASE, ctx->output_base);
+wrmsrl(MSR_IA32_RTIT_OUTPUT_MASK_PTRS, ctx->output_mask_ptrs);
+wrmsrl(MSR_IA32_RTIT_CR3_MATCH, ctx->cr3_match);
+for ( i = 0; i < addr_num; i++ )
+wrmsrl(MSR_IA32_RTIT_ADDR0_A + i, ctx->addr[i]);
+}
+
+static inline void pt_save_msr(struct pt_ctx *ctx, u32 addr_num)
+{
+u32 i;
+rdmsrl(MSR_IA32_RTIT_STATUS, ctx->status);
+rdmsrl(MSR_IA32_RTIT_OUTPUT_BASE, ctx->output_base);
+rdmsrl(MSR_IA32_RTIT_OUTPUT_MASK_PTRS, ctx->output_mask_ptrs);
+rdmsrl(MSR_IA32_RTIT_CR3_MATCH, ctx->cr3_match);
+for ( i = 0; i < addr_num; i++ )
+rdmsrl(MSR_IA32_RTIT_ADDR0_A + i, ctx->addr[i]);
+}
+
+void pt_guest_enter(struct vcpu *v)
+{
+struct pt_desc *pt = &v->arch.hvm_vmx.pt_desc;
+
+if ( pt->intel_pt_enabled )
+{
+vmx_vmcs_enter(v);
+__vmwrite(GUEST_IA32_RTIT_CTL, pt->guest_pt_ctx.ctl);
+vmx_vmcs_exit(v);
+
+pt_load_msr(&pt->guest_pt_ctx, pt->addr_num);
+}
+}
+
+void pt_guest_exit(struct vcpu *v)
+{
+struct pt_desc *pt = &v->arch.hvm_vmx.pt_desc;
+
+if ( pt->intel_pt_enabled )
+{
+vmx_vmcs_enter(v);
+__vmread(GUEST_IA32_RTIT_CTL, &pt->guest_pt_ctx.ctl);
+vmx_vmcs_exit(v);
+
+pt_save_msr(&pt->guest_pt_ctx, pt->addr_num);
+}
+}
+
+void pt_vcpu_init(struct vcpu *v)
+{
+struct pt_desc *pt = &v->arch.hvm_vmx.pt_desc;
+unsigned int eax, ebx, ecx, edx;
+
+memset(pt, 0, sizeof(struct pt_desc));
+pt->intel_pt_enabled = false;
+
+if ( !cpu_has_intel_pt || !opt_intel_pt ||
+ !(v->arch.hvm_vmx.secondary_exec_control & SECONDARY_EXEC_PT_USE_GPA) 
)
+return;
+
+/* get the number of address ranges */
+if ( cpuid_eax(0x14) == 1 )
+cpuid_count(0x14, 1, &eax, &ebx, &ecx, &edx);
+else
+return;
+
+pt->addr_num = eax & 0x7;
+pt->guest_pt_ctx.output_mask_ptrs = 0x7F;
+pt->intel_pt_enabled = true;
+
+vmx_vmcs_enter(v);
+__vmwrite(GUEST_IA32_RTIT_CTL, 0);
+vmx_vmcs_exit(v);
+}
diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c
index a5c2bd7..ea23dbd 100644
--- a/xen/arch/x86/hvm/vmx/vmx.c
+++ b/xen/arch/x86/hvm/vmx/vmx.c
@@ -468,6 +468,8 @@ static int vmx_vcpu_initialise(struct vcpu *v)
 if ( v->vcpu_id == 0 )
 v->arch.user_regs.rax = 1;
 
+pt_vcpu_init(v);
+
 return 0;
 }
 
@@ -3492,6 +3494,7 @@ void vmx_vmexit_handler(struct cpu_user_regs *regs)
 __vmread(GUEST_RSP,®s->rsp);
 __vmread(GUEST_RFLAGS, ®s->rflags);
 
+pt_guest_exit(v);
 hvm_invalidate_regs_fields(regs);
 
 if ( paging_mode_hap(v->domain) )
@@ -4260,6 +4263,7 @@ bool vmx_vmenter_helper(const struct cpu_user_regs *regs)
 }
 }
 
+pt_guest_enter(curr);
  out:
 if ( unlikely(curr->arch.hvm_vmx.lbr_fixup_enabled) )
 lbr_fixup();
diff --git a/xen/include/asm-x86/hvm/vmx/vmcs.h 
b/xen/include/asm-x86/hvm/vmx/vmcs.h
index 33ec3e6..46c386f 100644
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h
@@ -421,6 +421,8 @@ enum vmcs_field {
 GUEST_PDPTE0= 0x280a,
 #define GUEST_PDPTE(n) (GUEST_PDPTE0 + (n) * 2) /* n = 0...3 */
 GUEST_BNDCFGS   = 0x2812,
+GUEST_IA32_RTIT_CTL = 0x2814,
+GUEST_IA32_RTIT_CTL_HIGH= 0x2815,
 HOST_PAT= 0x2c00,
 HOST_EFER   = 0x2c02,
 HOST_PERF_GLOBAL_CTRL   = 0x2c04,
diff --git a/xen/include/asm-x86/intel_pt.h b/xen/include/asm-x86/intel_pt.h
index 78e3a37..29ea466 100644
--- a/xen/include/asm-x86/intel_pt.h
+++ b/xen/include/asm-x86/intel_pt.h
@@ -40,4 +40,8 @@ struct pt_desc {
 
 extern bool_t opt_intel_pt;
 
+void pt_vcpu_init(struct vcpu *v);
+void pt_guest_enter(struct vcpu *v);
+void pt_guest_exit(struct vcpu *v);
+
 #endif /* __ASM_X86_HVM_INTEL_PT_H_ */
-- 
1.8.3.1


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


[Xen-devel] [PATCH 1/6] x86: add a flag to enable Intel processor trace

2017-10-22 Thread Luwei Kang
This patch add a flag to enable Intel PT (Intel processor trace).
Default value is 1 (enabled).

Signed-off-by: Luwei Kang 
---
 docs/misc/xen-command-line.markdown |  7 +++
 xen/arch/x86/cpu/Makefile   |  1 +
 xen/arch/x86/cpu/intel_pt.c | 27 +++
 xen/include/asm-x86/intel_pt.h  | 26 ++
 4 files changed, 61 insertions(+)
 create mode 100644 xen/arch/x86/cpu/intel_pt.c
 create mode 100644 xen/include/asm-x86/intel_pt.h

diff --git a/docs/misc/xen-command-line.markdown 
b/docs/misc/xen-command-line.markdown
index eb4995e..a376932 100644
--- a/docs/misc/xen-command-line.markdown
+++ b/docs/misc/xen-command-line.markdown
@@ -1009,6 +1009,13 @@ debug hypervisor only).
 ### idle\_latency\_factor
 > `= `
 
+### intel\_pt
+> `= `
+
+> Default: `true`
+
+Flag to enable Intel Processor Trace.
+
 ### ioapic\_ack
 > `= old | new`
 
diff --git a/xen/arch/x86/cpu/Makefile b/xen/arch/x86/cpu/Makefile
index 74f23ae..33d7a74 100644
--- a/xen/arch/x86/cpu/Makefile
+++ b/xen/arch/x86/cpu/Makefile
@@ -8,3 +8,4 @@ obj-y += intel.o
 obj-y += intel_cacheinfo.o
 obj-y += mwait-idle.o
 obj-y += vpmu.o vpmu_amd.o vpmu_intel.o
+obj-y += intel_pt.o
diff --git a/xen/arch/x86/cpu/intel_pt.c b/xen/arch/x86/cpu/intel_pt.c
new file mode 100644
index 000..be06d55
--- /dev/null
+++ b/xen/arch/x86/cpu/intel_pt.c
@@ -0,0 +1,27 @@
+/*
+ * intel_pt.c: Support Intel Processor Trace Virtualization.
+ *
+ * Copyright (c) 2017, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Luwei Kang 
+ */
+
+#include 
+#include 
+#include 
+
+/* intel_pt: Flag to enable Intel Processor Trace (default on). */
+bool_t __read_mostly opt_intel_pt = 1;
+boolean_param("intel_pt", opt_intel_pt);
diff --git a/xen/include/asm-x86/intel_pt.h b/xen/include/asm-x86/intel_pt.h
new file mode 100644
index 000..3b3a047
--- /dev/null
+++ b/xen/include/asm-x86/intel_pt.h
@@ -0,0 +1,26 @@
+/*
+ * intel_pt.h: Intel Processor Trace virtualization for HVM domain.
+ *
+ * Copyright (c) 2017, Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Luwei Kang 
+ */
+
+#ifndef __ASM_X86_HVM_INTEL_PT_H_
+#define __ASM_X86_HVM_INTEL_PT_H_
+
+extern bool_t opt_intel_pt;
+
+#endif /* __ASM_X86_HVM_INTEL_PT_H_ */
-- 
1.8.3.1


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


[Xen-devel] [PATCH 0/6] Intel Processor Trace virtulization enabling

2017-10-22 Thread Luwei Kang
Hi All,

Here is a patch-series which adding Processor Trace enabling in XEN guest. You 
can get It's software developer manuals from:
https://software.intel.com/sites/default/files/managed/c5/15/architecture-instruction-set-extensions-programming-reference.pdf
In Chapter 5 INTEL PROCESSOR TRACE: VMX IMPROVEMENTS.

Introduction:
Intel Processor Trace (Intel PT) is an extension of Intel Architecture that 
captures information about software execution using dedicated hardware 
facilities that cause only minimal performance perturbation to the software 
being traced. Details on the Intel PT infrastructure and trace capabilities can 
be found in the Intel 64 and IA-32 Architectures Software Developer’s Manual, 
Volume 3C.

The suite of architecture changes serve to simplify the process of virtualizing 
Intel PT for use by a guest software. There are two primary elements to this 
new architecture support for VMX support improvements made for Intel PT.
1. Addition of a new guest IA32_RTIT_CTL value field to the VMCS.
  — This serves to speed and simplify the process of disabling trace on VM 
exit, and restoring it on VM entry.
2. Enabling use of EPT to redirect PT output.
  — This enables the VMM to elect to virtualize the PT output buffer using EPT. 
In this mode, the CPU will treat PT output addresses as Guest Physical 
Addresses (GPAs) and translate them using EPT. This means that Intel PT output 
reads (of the ToPA table) and writes (of trace output) can cause EPT 
violations, and other output events.


Luwei Kang (6):
  x86: add a flag to enable Intel processor trace
  x86: configure vmcs for Intel processor trace virtualization
  x86: add intel proecessor trace support for cpuid
  x86: add intel processor trace context
  x86: implement intel processor trace context switch
  x86: Pass through intel processor trace MSRs

 docs/misc/xen-command-line.markdown |   7 ++
 tools/libxc/xc_cpuid_x86.c  |  12 ++-
 xen/arch/x86/cpu/Makefile   |   1 +
 xen/arch/x86/cpu/intel_pt.c | 114 
 xen/arch/x86/cpuid.c|  22 ++
 xen/arch/x86/domctl.c   |   4 +
 xen/arch/x86/hvm/vmx/vmcs.c |  36 +++--
 xen/arch/x86/hvm/vmx/vmx.c  |   4 +
 xen/include/asm-x86/cpufeature.h|   1 +
 xen/include/asm-x86/cpuid.h |  12 ++-
 xen/include/asm-x86/hvm/vmx/vmcs.h  |  12 +++
 xen/include/asm-x86/intel_pt.h  |  47 
 xen/include/asm-x86/msr-index.h |  16 
 xen/include/public/arch-x86/cpufeatureset.h |   1 +
 14 files changed, 281 insertions(+), 8 deletions(-)
 create mode 100644 xen/arch/x86/cpu/intel_pt.c
 create mode 100644 xen/include/asm-x86/intel_pt.h

-- 
1.8.3.1


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


[Xen-devel] [PATCH v4] x86/vpmu: add cpu hot unplug notifier for vpmu

2017-05-23 Thread Luwei Kang
Currently, Hot unplug a physical CPU with vpmu enabled may cause
system hang due to send a remote call to an offlined pCPU. This
patch add a cpu hot unplug notifer to save vpmu context before
cpu offline.

Consider one scenario, hot unplug pCPU N with vpmu enabled.
The vcpu which running on this pCPU will be switch to other
online cpu. A remote call will be send to pCPU N to save the
vpmu context before loading the vpmu context on this pCPU.
System will hang in function on_select_cpus() because of that
pCPU is offlined and can not do any respond.

The purpose of add a VPMU_CONTEXT_LOADED check in vpmu_arch_destroy()
before send a remote call to save vpmu contex is:
a. when a vpmu context has been loaded in a remote pCPU, make a
   remote call to save the vpmu contex and stop counters is necessary.
b. VPMU_CONTEXT_LOADED flag will be reset if a pCPU is offlined.
   this check will prevent send a remote call to an offlined pCPU.

Signed-off-by: Luwei Kang 
---
v4:
 1.remove cpu_online() check in vpm_load();
 2.remove "vpmu_" prefix;
 3.fix a coding style;
 4.add some commit message about VPMU_CONTEXT_LOADED in vpmu_arch_destroy();
v3:
 1.add cpu_online() check in vpm_load() and vpmu_arch_destroy();
 2.add vpmu_ prefix. rename cpu_callback() to vpmu_cpu_callback();
v2:
 1.fix some typo and coding style;
 2.change "swith" to "if" in cpu_callback() because of there just have one case;
 3.add VPMU_CONTEX_LOADED check before send remote call in vpmu_arch_destroy();
---
 xen/arch/x86/cpu/vpmu.c | 45 +
 1 file changed, 41 insertions(+), 4 deletions(-)

diff --git a/xen/arch/x86/cpu/vpmu.c b/xen/arch/x86/cpu/vpmu.c
index 03401fd..1f7830b 100644
--- a/xen/arch/x86/cpu/vpmu.c
+++ b/xen/arch/x86/cpu/vpmu.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -575,15 +576,21 @@ static void vpmu_arch_destroy(struct vcpu *v)
  * We will test it again in vpmu_clear_last() with interrupts
  * disabled to make sure we don't clear someone else.
  */
-if ( per_cpu(last_vcpu, vpmu->last_pcpu) == v )
+if ( cpu_online(vpmu->last_pcpu) &&
+ per_cpu(last_vcpu, vpmu->last_pcpu) == v )
 on_selected_cpus(cpumask_of(vpmu->last_pcpu),
  vpmu_clear_last, v, 1);
 
 if ( vpmu->arch_vpmu_ops && vpmu->arch_vpmu_ops->arch_vpmu_destroy )
 {
-/* Unload VPMU first. This will stop counters */
-on_selected_cpus(cpumask_of(vcpu_vpmu(v)->last_pcpu),
- vpmu_save_force, v, 1);
+/*
+ * Unload VPMU first if VPMU_CONTEXT_LOADED being set.
+ * This will stop counters.
+ */
+if ( vpmu_is_set(vpmu, VPMU_CONTEXT_LOADED) )
+on_selected_cpus(cpumask_of(vcpu_vpmu(v)->last_pcpu),
+ vpmu_save_force, v, 1);
+
  vpmu->arch_vpmu_ops->arch_vpmu_destroy(v);
 }
 }
@@ -835,6 +842,33 @@ long do_xenpmu_op(unsigned int op, 
XEN_GUEST_HANDLE_PARAM(xen_pmu_params_t) arg)
 return ret;
 }
 
+static int cpu_callback(
+struct notifier_block *nfb, unsigned long action, void *hcpu)
+{
+unsigned int cpu = (unsigned long)hcpu;
+struct vcpu *vcpu = per_cpu(last_vcpu, cpu);
+struct vpmu_struct *vpmu;
+
+if ( !vcpu )
+return NOTIFY_DONE;
+
+vpmu = vcpu_vpmu(vcpu);
+if ( !vpmu_is_set(vpmu, VPMU_CONTEXT_ALLOCATED) )
+return NOTIFY_DONE;
+
+if ( action == CPU_DYING )
+{
+vpmu_save_force(vcpu);
+vpmu_reset(vpmu, VPMU_CONTEXT_LOADED);
+}
+
+return NOTIFY_DONE;
+}
+
+static struct notifier_block cpu_nfb = {
+.notifier_call = cpu_callback
+};
+
 static int __init vpmu_init(void)
 {
 int vendor = current_cpu_data.x86_vendor;
@@ -872,8 +906,11 @@ static int __init vpmu_init(void)
 }
 
 if ( vpmu_mode != XENPMU_MODE_OFF )
+{
+register_cpu_notifier(&cpu_nfb);
 printk(XENLOG_INFO "VPMU: version " __stringify(XENPMU_VER_MAJ) "."
__stringify(XENPMU_VER_MIN) "\n");
+}
 else
 opt_vpmu_enabled = 0;
 
-- 
1.8.3.1


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


[Xen-devel] [PATCH v3] x86/vpmu: add cpu hot unplug notifier for vpmu

2017-05-21 Thread Luwei Kang
Currently, Hot unplug a physical CPU with vpmu enabled may cause
system hang due to send a remote call to an offlined pCPU. This
patch add a cpu hot unplug notifer to save vpmu context before
cpu offline.

Consider one scenario, hot unplug pCPU N with vpmu enabled.
The vcpu which running on this pCPU will be switch to other
online cpu. A remote call will be send to pCPU N to save the
vpmu context before loading the vpmu context on this pCPU.
System will hang in function on_select_cpus() because of that pCPU
is offlined and can not do any respond.

Signed-off-by: Luwei Kang 
---
v3:
 1.add cpu_online() check in vpm_load() and vpmu_arch_destroy();
 2.add vpmu_ prefix. rename cpu_callback() to vpmu_cpu_callback();
v2:
 1.fix some typo and coding style;
 2.change "swith" to "if" in cpu_callback() because of there just have one case;
 3.add VPMU_CONTEX_LOADED check before send remote call in vpmu_arch_destroy();
---
 xen/arch/x86/cpu/vpmu.c | 52 +++--
 1 file changed, 46 insertions(+), 6 deletions(-)

diff --git a/xen/arch/x86/cpu/vpmu.c b/xen/arch/x86/cpu/vpmu.c
index 03401fd..486af12 100644
--- a/xen/arch/x86/cpu/vpmu.c
+++ b/xen/arch/x86/cpu/vpmu.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -394,8 +395,11 @@ int vpmu_load(struct vcpu *v, bool_t from_guest)
 if ( !vpmu_is_set(vpmu, VPMU_CONTEXT_ALLOCATED) )
 return 0;
 
-/* First time this VCPU is running here */
-if ( vpmu->last_pcpu != pcpu )
+/*
+ * The last pCPU is still online and this is the first time this vCPU
+ * running here.
+ */
+if ( cpu_online(vpmu->last_pcpu) && vpmu->last_pcpu != pcpu )
 {
 /*
  * Get the context from last pcpu that we ran on. Note that if another
@@ -575,15 +579,21 @@ static void vpmu_arch_destroy(struct vcpu *v)
  * We will test it again in vpmu_clear_last() with interrupts
  * disabled to make sure we don't clear someone else.
  */
-if ( per_cpu(last_vcpu, vpmu->last_pcpu) == v )
+if ( cpu_online(vpmu->last_pcpu) &&
+per_cpu(last_vcpu, vpmu->last_pcpu) == v )
 on_selected_cpus(cpumask_of(vpmu->last_pcpu),
  vpmu_clear_last, v, 1);
 
 if ( vpmu->arch_vpmu_ops && vpmu->arch_vpmu_ops->arch_vpmu_destroy )
 {
-/* Unload VPMU first. This will stop counters */
-on_selected_cpus(cpumask_of(vcpu_vpmu(v)->last_pcpu),
- vpmu_save_force, v, 1);
+/*
+ * Unload VPMU first if VPMU_CONTEXT_LOADED being set.
+ * This will stop counters.
+ */
+if ( vpmu_is_set(vpmu, VPMU_CONTEXT_LOADED) )
+on_selected_cpus(cpumask_of(vcpu_vpmu(v)->last_pcpu),
+ vpmu_save_force, v, 1);
+
  vpmu->arch_vpmu_ops->arch_vpmu_destroy(v);
 }
 }
@@ -835,6 +845,33 @@ long do_xenpmu_op(unsigned int op, 
XEN_GUEST_HANDLE_PARAM(xen_pmu_params_t) arg)
 return ret;
 }
 
+static int vpmu_cpu_callback(
+struct notifier_block *nfb, unsigned long action, void *hcpu)
+{
+unsigned int cpu = (unsigned long)hcpu;
+struct vcpu *vcpu = per_cpu(last_vcpu, cpu);
+struct vpmu_struct *vpmu;
+
+if ( !vcpu )
+return NOTIFY_DONE;
+
+vpmu = vcpu_vpmu(vcpu);
+if ( !vpmu_is_set(vpmu, VPMU_CONTEXT_ALLOCATED) )
+return NOTIFY_DONE;
+
+if ( action == CPU_DYING )
+{
+vpmu_save_force(vcpu);
+vpmu_reset(vpmu, VPMU_CONTEXT_LOADED);
+}
+
+return NOTIFY_DONE;
+}
+
+static struct notifier_block vpmu_cpu_nfb = {
+.notifier_call = vpmu_cpu_callback
+};
+
 static int __init vpmu_init(void)
 {
 int vendor = current_cpu_data.x86_vendor;
@@ -872,8 +909,11 @@ static int __init vpmu_init(void)
 }
 
 if ( vpmu_mode != XENPMU_MODE_OFF )
+{
+register_cpu_notifier(&vpmu_cpu_nfb);
 printk(XENLOG_INFO "VPMU: version " __stringify(XENPMU_VER_MAJ) "."
__stringify(XENPMU_VER_MIN) "\n");
+}
 else
 opt_vpmu_enabled = 0;
 
-- 
1.8.3.1


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


[Xen-devel] [PATCH v2] x86/vpmu: add cpu hot unplug notifier for vpmu

2017-05-17 Thread Luwei Kang
Currently, Hot unplug a physical CPU with vpmu enabled may cause
system hang due to send a remote call to an offlined pCPU. This
patch add a cpu hot unplug notifer to save vpmu context before
cpu offline.

Consider one scenario, hot unplug pCPU N with vpmu enabled.
The vcpu which running on this pCPU will be switch to other
online cpu. A remote call will be send to pCPU N to save the 
vpmu context before loading the vpmu context on this pCPU.
System will hang in function on_select_cpus() because of that pCPU
is offlined and can not do any respond.

Signed-off-by: Luwei Kang 
---
v2:
 1.fix some typo and coding style;
 2.change "swith" to "if" in cpu_callback() because of there just have one case;
 3.add VPMU_CONTEX_LOADED check before send remote call in vpmu_arch_destroy();
---
 xen/arch/x86/cpu/vpmu.c | 42 +++---
 1 file changed, 39 insertions(+), 3 deletions(-)

diff --git a/xen/arch/x86/cpu/vpmu.c b/xen/arch/x86/cpu/vpmu.c
index 03401fd..57a0e9d 100644
--- a/xen/arch/x86/cpu/vpmu.c
+++ b/xen/arch/x86/cpu/vpmu.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -581,9 +582,14 @@ static void vpmu_arch_destroy(struct vcpu *v)
 
 if ( vpmu->arch_vpmu_ops && vpmu->arch_vpmu_ops->arch_vpmu_destroy )
 {
-/* Unload VPMU first. This will stop counters */
-on_selected_cpus(cpumask_of(vcpu_vpmu(v)->last_pcpu),
- vpmu_save_force, v, 1);
+/*
+ * Unload VPMU first if VPMU_CONTEXT_LOADED being set.
+ * This will stop counters.
+ */
+if ( vpmu_is_set(vpmu, VPMU_CONTEXT_LOADED) )
+on_selected_cpus(cpumask_of(vcpu_vpmu(v)->last_pcpu),
+ vpmu_save_force, v, 1);
+
  vpmu->arch_vpmu_ops->arch_vpmu_destroy(v);
 }
 }
@@ -835,6 +841,33 @@ long do_xenpmu_op(unsigned int op, 
XEN_GUEST_HANDLE_PARAM(xen_pmu_params_t) arg)
 return ret;
 }
 
+static int cpu_callback(
+struct notifier_block *nfb, unsigned long action, void *hcpu)
+{
+unsigned int cpu = (unsigned long)hcpu;
+struct vcpu *vcpu = per_cpu(last_vcpu, cpu);
+struct vpmu_struct *vpmu;
+
+if ( !vcpu )
+return NOTIFY_DONE;
+
+vpmu = vcpu_vpmu(vcpu);
+if ( !vpmu_is_set(vpmu, VPMU_CONTEXT_ALLOCATED) )
+return NOTIFY_DONE;
+
+if ( action == CPU_DYING )
+{
+vpmu_save_force(vcpu);
+vpmu_reset(vpmu, VPMU_CONTEXT_LOADED);
+}
+
+return NOTIFY_DONE;
+}
+
+static struct notifier_block vpmu_cpu_nfb = {
+.notifier_call = cpu_callback
+};
+
 static int __init vpmu_init(void)
 {
 int vendor = current_cpu_data.x86_vendor;
@@ -872,8 +905,11 @@ static int __init vpmu_init(void)
 }
 
 if ( vpmu_mode != XENPMU_MODE_OFF )
+{
+register_cpu_notifier(&vpmu_cpu_nfb);
 printk(XENLOG_INFO "VPMU: version " __stringify(XENPMU_VER_MAJ) "."
__stringify(XENPMU_VER_MIN) "\n");
+}
 else
 opt_vpmu_enabled = 0;
 
-- 
1.8.3.1


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


[Xen-devel] [PATCH] x86/vpmu: add cpu hot unplug notifier for vpmu

2017-05-17 Thread Luwei Kang
Currently, hot unplug a cpu with vpmu enabled may cause system
hang due to send IPI to a die physical cpu. This patch add a
cpu hot unplug notifer to save vpmu context before cpu offline.

Consider one scene, hotplug physical cpu N with vpmu is enabled.
The vcpu which running on this physical cpu before will be switch
to other online cpu. Before load the vpmu context to new physical
cpu, a IPI will be send to cpu N to save the vpmu context.
System will hang in function on_select_cpus because of that
physical cpu is offline and can not do any response.

Signed-off-by: Luwei Kang 
---
 xen/arch/x86/cpu/vpmu.c | 36 ++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/xen/arch/x86/cpu/vpmu.c b/xen/arch/x86/cpu/vpmu.c
index 03401fd..89e0ea8 100644
--- a/xen/arch/x86/cpu/vpmu.c
+++ b/xen/arch/x86/cpu/vpmu.c
@@ -35,6 +35,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 CHECK_pmu_cntr_pair;
@@ -835,6 +836,36 @@ long do_xenpmu_op(unsigned int op, 
XEN_GUEST_HANDLE_PARAM(xen_pmu_params_t) arg)
 return ret;
 }
 
+static int cpu_callback(struct notifier_block *nfb, unsigned long action, void 
*hcpu)
+{
+unsigned int cpu = (unsigned long)hcpu;
+struct vcpu *vcpu = per_cpu(last_vcpu, cpu);
+struct vpmu_struct *vpmu;
+
+if ( !vcpu )
+return NOTIFY_DONE;
+
+vpmu = vcpu_vpmu(vcpu);
+if ( !vpmu_is_set(vpmu, VPMU_CONTEXT_ALLOCATED) )
+return NOTIFY_DONE;
+
+switch ( action )
+{
+case CPU_DYING:
+vpmu_save_force(vcpu);
+vpmu_reset(vpmu, VPMU_CONTEXT_LOADED);
+break;
+default:
+break;
+}
+
+return NOTIFY_DONE;
+}
+
+static struct notifier_block vpmu_cpu_nfb = {
+.notifier_call = cpu_callback
+};
+
 static int __init vpmu_init(void)
 {
 int vendor = current_cpu_data.x86_vendor;
@@ -871,10 +902,11 @@ static int __init vpmu_init(void)
 break;
 }
 
-if ( vpmu_mode != XENPMU_MODE_OFF )
+if ( vpmu_mode != XENPMU_MODE_OFF ) {
+register_cpu_notifier(&vpmu_cpu_nfb);
 printk(XENLOG_INFO "VPMU: version " __stringify(XENPMU_VER_MAJ) "."
__stringify(XENPMU_VER_MIN) "\n");
-else
+} else
 opt_vpmu_enabled = 0;
 
 return 0;
-- 
1.8.3.1


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


[Xen-devel] [PATCH V2] tools:misc:xenpm: set max freq to all cpu with default cpuid

2017-04-13 Thread Luwei Kang
User can set max freq to specific cpu by
"xenpm set-scaling-maxfreq [cpuid] "
or set max freq to all cpu with default cpuid by
"xenpm set-scaling-maxfreq ".

Set max freq with default cpuid will cause
segmentation fault after commit id d4906b5d05.
This patch will fix this issue and add ability
to set max freq with default cpuid.

Signed-off-by: Luwei Kang 
---
 tools/misc/xenpm.c | 8 +---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/tools/misc/xenpm.c b/tools/misc/xenpm.c
index ded40b9..762311e 100644
--- a/tools/misc/xenpm.c
+++ b/tools/misc/xenpm.c
@@ -99,10 +99,12 @@ static void parse_cpuid_and_int(int argc, char *argv[],
  exit(EINVAL);
 }
 
-parse_cpuid(argv[0], cpuid);
-if ( sscanf(argv[1], "%d", val) != 1 )
+if ( argc > 1 )
+parse_cpuid(argv[0], cpuid);
+
+if ( sscanf(argv[argc > 1], "%d", val) != 1 )
 {
-fprintf(stderr, "Invalid %s '%s'\n", what, argv[1]);
+fprintf(stderr, "Invalid %s '%s'\n", what, argv[argc > 1]);
 exit(EINVAL);
 }
 }
-- 
1.8.3.1


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


[Xen-devel] [PATCH] tools:misc:xenpm: set max freq to all cpu with default cpuid

2017-04-11 Thread Luwei Kang
User can set max freq to specific cpu by
"xenpm set-scaling-maxfreq  "
or set max freq to all cpu with default cpuid by
"xenpm set-scaling-maxfreq ".

Set max freq with defaule cpuid will cause
segmentation fault after commit id d4906b5d05.
This patch will fix this issue and add ability
to set max freq with default cpuid.

Signed-off-by: Luwei Kang 
---
 tools/misc/xenpm.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/tools/misc/xenpm.c b/tools/misc/xenpm.c
index ded40b9..abe31b5 100644
--- a/tools/misc/xenpm.c
+++ b/tools/misc/xenpm.c
@@ -99,8 +99,10 @@ static void parse_cpuid_and_int(int argc, char *argv[],
  exit(EINVAL);
 }
 
-parse_cpuid(argv[0], cpuid);
-if ( sscanf(argv[1], "%d", val) != 1 )
+if ( argc > 1 )
+parse_cpuid(argv[0], cpuid);
+
+if ( argc == 0 || sscanf(argv[argc > 1], "%d", val) != 1 )
 {
 fprintf(stderr, "Invalid %s '%s'\n", what, argv[1]);
 exit(EINVAL);
-- 
1.8.3.1


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


[Xen-devel] [PATCH] x86/vpmu: fix vpmu can't enabled in guest

2017-02-13 Thread Luwei Kang
vpmu_enable() can not use for check if vpmu is enabled in guest during
booting up. Because linux kernel get the status of if supported pmu
is earler than xen vpmu initialise. vpmu_enable() will return false
even if vpmu has been enabled in guest.

Signed-off-by: Luwei Kang 
---
 xen/arch/x86/cpu/vpmu.c|  2 +-
 xen/arch/x86/cpuid.c   | 11 +--
 xen/include/asm-x86/vpmu.h |  2 +-
 3 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/xen/arch/x86/cpu/vpmu.c b/xen/arch/x86/cpu/vpmu.c
index 35a9403..8c8ffc9 100644
--- a/xen/arch/x86/cpu/vpmu.c
+++ b/xen/arch/x86/cpu/vpmu.c
@@ -50,7 +50,7 @@ CHECK_pmu_params;
  * "vpmu=arch" : vpmu enabled for predef arch counters only (restrictive)
  * flag combinations are allowed, eg, "vpmu=ipc,bts".
  */
-static unsigned int __read_mostly opt_vpmu_enabled;
+unsigned int __read_mostly opt_vpmu_enabled;
 unsigned int __read_mostly vpmu_mode = XENPMU_MODE_OFF;
 unsigned int __read_mostly vpmu_features = 0;
 static void parse_vpmu_params(char *s);
diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c
index e0a387e..b63c5d8 100644
--- a/xen/arch/x86/cpuid.c
+++ b/xen/arch/x86/cpuid.c
@@ -713,8 +713,7 @@ static void pv_cpuid(uint32_t leaf, uint32_t subleaf, 
struct cpuid_leaf *res)
 }
 }
 
-if ( vpmu_enabled(curr) &&
- vpmu_is_set(vcpu_vpmu(curr), VPMU_CPU_HAS_DS) )
+if ( opt_vpmu_enabled && boot_cpu_has(X86_FEATURE_DS) )
 {
 res->d |= cpufeat_mask(X86_FEATURE_DS);
 if ( cpu_has(¤t_cpu_data, X86_FEATURE_DTES64) )
@@ -726,7 +725,7 @@ static void pv_cpuid(uint32_t leaf, uint32_t subleaf, 
struct cpuid_leaf *res)
 
 case 0x000a: /* Architectural Performance Monitor Features (Intel) */
 if ( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
- !vpmu_enabled(curr) )
+ !opt_vpmu_enabled )
 goto unsupported;
 
 /* Report at most version 3 since that's all we currently emulate. */
@@ -793,8 +792,7 @@ static void hvm_cpuid(uint32_t leaf, uint32_t subleaf, 
struct cpuid_leaf *res)
 if ( !hap_enabled(d) && !hvm_pae_enabled(v) )
 res->d &= ~cpufeat_mask(X86_FEATURE_PSE36);
 
-if ( vpmu_enabled(v) &&
- vpmu_is_set(vcpu_vpmu(v), VPMU_CPU_HAS_DS) )
+if ( opt_vpmu_enabled && boot_cpu_has(X86_FEATURE_DS) )
 {
 res->d |= cpufeat_mask(X86_FEATURE_DS);
 if ( cpu_has(¤t_cpu_data, X86_FEATURE_DTES64) )
@@ -811,7 +809,8 @@ static void hvm_cpuid(uint32_t leaf, uint32_t subleaf, 
struct cpuid_leaf *res)
 break;
 
 case 0x000a: /* Architectural Performance Monitor Features (Intel) */
-if ( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL || !vpmu_enabled(v) )
+if ( boot_cpu_data.x86_vendor != X86_VENDOR_INTEL ||
+   !opt_vpmu_enabled )
 {
 *res = EMPTY_LEAF;
 break;
diff --git a/xen/include/asm-x86/vpmu.h b/xen/include/asm-x86/vpmu.h
index e50618f..1148d66 100644
--- a/xen/include/asm-x86/vpmu.h
+++ b/xen/include/asm-x86/vpmu.h
@@ -25,7 +25,6 @@
 
 #define vcpu_vpmu(vcpu)   (&(vcpu)->arch.vpmu)
 #define vpmu_vcpu(vpmu)   container_of((vpmu), struct vcpu, arch.vpmu)
-#define vpmu_enabled(vcpu) vpmu_is_set(vcpu_vpmu(vcpu), VPMU_CONTEXT_ALLOCATED)
 
 #define MSR_TYPE_COUNTER0
 #define MSR_TYPE_CTRL   1
@@ -121,6 +120,7 @@ static inline int vpmu_do_rdmsr(unsigned int msr, uint64_t 
*msr_content)
 return vpmu_do_msr(msr, msr_content, 0, 0);
 }
 
+extern unsigned int opt_vpmu_enabled;
 extern unsigned int vpmu_mode;
 extern unsigned int vpmu_features;
 
-- 
1.8.3.1


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


[Xen-devel] [PATCH v2] X86/VPMU:clear the overflow status of which counter happened overflow

2016-12-12 Thread Luwei Kang
just set the corresponding bits of which counter happened overflow,
rather than set all the available bits of IA32_PERF_GLOBAL_OVF_CTRL
when happened pmu interrupt.

Signed-off-by: Luwei Kang 
---
v2:modify the description of this patch.
---
 xen/arch/x86/cpu/vpmu_intel.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/x86/cpu/vpmu_intel.c b/xen/arch/x86/cpu/vpmu_intel.c
index e8049ed..613aafe 100644
--- a/xen/arch/x86/cpu/vpmu_intel.c
+++ b/xen/arch/x86/cpu/vpmu_intel.c
@@ -868,7 +868,7 @@ static int core2_vpmu_do_interrupt(struct cpu_user_regs 
*regs)
 if ( is_pmc_quirk )
 handle_pmc_quirk(msr_content);
 core2_vpmu_cxt->global_status |= msr_content;
-msr_content = ~global_ovf_ctrl_mask;
+msr_content &= ~global_ovf_ctrl_mask;
 wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, msr_content);
 }
 else
-- 
2.7.4


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


[Xen-devel] [PATCH] X86/VPMU:clear the overflow status of which counter happened overflow

2016-12-12 Thread Luwei Kang
If a counter happend overflow just clear corresponding bit of
IA32_PERF_GLOBAL_OVF_CTRL, rather than clear all the bit of this msr.

Signed-off-by: Luwei Kang 
---
 xen/arch/x86/cpu/vpmu_intel.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xen/arch/x86/cpu/vpmu_intel.c b/xen/arch/x86/cpu/vpmu_intel.c
index e8049ed..613aafe 100644
--- a/xen/arch/x86/cpu/vpmu_intel.c
+++ b/xen/arch/x86/cpu/vpmu_intel.c
@@ -868,7 +868,7 @@ static int core2_vpmu_do_interrupt(struct cpu_user_regs 
*regs)
 if ( is_pmc_quirk )
 handle_pmc_quirk(msr_content);
 core2_vpmu_cxt->global_status |= msr_content;
-msr_content = ~global_ovf_ctrl_mask;
+msr_content &= ~global_ovf_ctrl_mask;
 wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, msr_content);
 }
 else
-- 
1.8.3.1


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


[Xen-devel] [PATCH] X86/VPMU: mask off uncore overflow bit on xeon phi knights landing

2016-12-08 Thread Luwei Kang
IA32_PERF_GLOBAL_STATUS.OvfUncore (MSR 38EH, bit[61]) is always 0 and
writing 1 to IA32_PERF_GLOBAL_OVF_CTRL.ClrOvfUncore (MSR 390H, bit[61])
signals #GP.
Reference "Intel Xeon Phi Procssor x200 Product Family", document
number 334646-008.

Signed-off-by: Luwei Kang 
---
 xen/arch/x86/cpu/vpmu_intel.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/xen/arch/x86/cpu/vpmu_intel.c b/xen/arch/x86/cpu/vpmu_intel.c
index e8049ed..0be78ff 100644
--- a/xen/arch/x86/cpu/vpmu_intel.c
+++ b/xen/arch/x86/cpu/vpmu_intel.c
@@ -1058,11 +1058,17 @@ int __init core2_vpmu_init(void)
  (((1ULL << fixed_pmc_cnt) - 1) << 32) |
  ((1ULL << arch_pmc_cnt) - 1));
 if ( version > 2 )
+{
 /*
  * Even though we don't support Uncore counters guests should be
  * able to clear all available overflows.
  */
 global_ovf_ctrl_mask &= ~(1ULL << 61);
+/* Knight Landing doesn't support overflow bit on uncore counters */
+if ( current_cpu_data.x86_model == 0x57 )
+global_ovf_ctrl_mask |= (1ULL << 61);
+
+}
 
 regs_sz = (sizeof(struct xen_pmu_intel_ctxt) - regs_off) +
   sizeof(uint64_t) * fixed_pmc_cnt +
-- 
1.8.3.1


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


[Xen-devel] [PATCH] tools/libxc: Add xstate cpuid leaf of avx512

2016-11-04 Thread Luwei Kang
Enable get xstate cpuid leaf information regarding avx512 in guest.

Signed-off-by: Luwei Kang 
---
 tools/libxc/xc_cpuid_x86.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
index de06b32..d761805 100644
--- a/tools/libxc/xc_cpuid_x86.c
+++ b/tools/libxc/xc_cpuid_x86.c
@@ -406,6 +406,9 @@ static void intel_xc_cpuid_policy(xc_interface *xch,
 #define X86_XCR0_AVX(1ULL <<  2)
 #define X86_XCR0_BNDREG (1ULL <<  3)
 #define X86_XCR0_BNDCSR (1ULL <<  4)
+#define X86_XCR0_OPMASK (1ULL <<  5)
+#define X86_XCR0_ZMM(1ULL <<  6)
+#define X86_XCR0_HI_ZMM (1ULL <<  7)
 #define X86_XCR0_PKRU   (1ULL <<  9)
 #define X86_XCR0_LWP(1ULL << 62)
 
@@ -437,6 +440,9 @@ static void xc_cpuid_config_xsave(xc_interface *xch,
 if ( test_bit(X86_FEATURE_MPX, info->featureset) )
 guest_xfeature_mask |= X86_XCR0_BNDREG | X86_XCR0_BNDCSR;
 
+if ( test_bit(X86_FEATURE_AVX512F, info->featureset) )
+guest_xfeature_mask |= X86_XCR0_OPMASK | X86_XCR0_ZMM | 
X86_XCR0_HI_ZMM;
+
 if ( test_bit(X86_FEATURE_PKU, info->featureset) )
 guest_xfeature_mask |= X86_XCR0_PKRU;
 
-- 
2.7.4


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


[Xen-devel] [PATCH v5] x86/cpuid: AVX-512 Feature Detection

2016-08-22 Thread Luwei Kang
AVX512 is an extention of AVX2. Its spec can be found at:
https://software.intel.com/sites/default/files/managed/b4/3a/319433-024.pdf
This patch detects AVX512 features by CPUID.

Signed-off-by: Luwei Kang 
---
[V5]:
Modify the comment of dependency between AVX512 and AVX2.
[V4]:
Update the description about features dependency.
[V3]:
Adjust dependencies between features.
[V2]:
1.get max xstate_size from each bit.
2.change get cpuid function parameter from 0x07 to 7.
3.add dependencies between features in xen/tools/gen-cpuid.py.
4.split the cpuid call just like the way the hvm_cpuid() side works.
---
 xen/arch/x86/hvm/hvm.c  | 14 ++
 xen/arch/x86/traps.c| 22 +-
 xen/include/public/arch-x86/cpufeatureset.h |  9 +
 xen/tools/gen-cpuid.py  | 10 ++
 4 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 7f99087..edea87e 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -3472,6 +3472,20 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, 
unsigned int *ebx,
   xstate_sizes[_XSTATE_BNDCSR]);
 }
 
+if ( _ebx & cpufeat_mask(X86_FEATURE_AVX512F) )
+{
+xfeature_mask |= XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM;
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_OPMASK] +
+  xstate_sizes[_XSTATE_OPMASK]);
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_ZMM] +
+  xstate_sizes[_XSTATE_ZMM]);
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_HI_ZMM] +
+  xstate_sizes[_XSTATE_HI_ZMM]);
+}
+
 if ( _ecx & cpufeat_mask(X86_FEATURE_PKU) )
 {
 xfeature_mask |= XSTATE_PKRU;
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 767d0b0..8fb697b 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -975,7 +975,7 @@ void pv_cpuid(struct cpu_user_regs *regs)
 
 switch ( leaf )
 {
-uint32_t tmp, _ecx;
+uint32_t tmp, _ecx, _ebx;
 
 case 0x0001:
 c &= pv_featureset[FEATURESET_1c];
@@ -1157,6 +1157,26 @@ void pv_cpuid(struct cpu_user_regs *regs)
xstate_sizes[_XSTATE_YMM]);
 }
 
+if ( !is_control_domain(currd) && !is_hardware_domain(currd) )
+domain_cpuid(currd, 7, 0, &tmp, &_ebx, &tmp, &tmp);
+else
+cpuid_count(7, 0, &tmp, &_ebx, &tmp, &tmp);
+_ebx &= pv_featureset[FEATURESET_7b0];
+
+if ( _ebx & cpufeat_mask(X86_FEATURE_AVX512F) )
+{
+xfeature_mask |= XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM;
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_OPMASK] +
+  xstate_sizes[_XSTATE_OPMASK]);
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_ZMM] +
+  xstate_sizes[_XSTATE_ZMM]);
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_HI_ZMM] +
+  xstate_sizes[_XSTATE_HI_ZMM]);
+}
+
 a = (uint32_t)xfeature_mask;
 d = (uint32_t)(xfeature_mask >> 32);
 c = xstate_size;
diff --git a/xen/include/public/arch-x86/cpufeatureset.h 
b/xen/include/public/arch-x86/cpufeatureset.h
index 39acf8c..9320c9e 100644
--- a/xen/include/public/arch-x86/cpufeatureset.h
+++ b/xen/include/public/arch-x86/cpufeatureset.h
@@ -206,15 +206,24 @@ XEN_CPUFEATURE(PQM,   5*32+12) /*   Platform QoS 
Monitoring */
 XEN_CPUFEATURE(NO_FPU_SEL,5*32+13) /*!  FPU CS/DS stored as zero */
 XEN_CPUFEATURE(MPX,   5*32+14) /*S  Memory Protection Extensions */
 XEN_CPUFEATURE(PQE,   5*32+15) /*   Platform QoS Enforcement */
+XEN_CPUFEATURE(AVX512F,   5*32+16) /*A  AVX-512 Foundation Instructions */
+XEN_CPUFEATURE(AVX512DQ,  5*32+17) /*A  AVX-512 Doubleword & Quadword 
Instrs */
 XEN_CPUFEATURE(RDSEED,5*32+18) /*A  RDSEED instruction */
 XEN_CPUFEATURE(ADX,   5*32+19) /*A  ADCX, ADOX instructions */
 XEN_CPUFEATURE(SMAP,  5*32+20) /*S  Supervisor Mode Access Prevention 
*/
+XEN_CPUFEATURE(AVX512IFMA,5*32+21) /*A  AVX-512 Integer Fused Multiply Add 
*/
 XEN_CPUFEATURE(CLFLUSHOPT,5*32+23) /*A  CLFLUSHOPT instruction */
 XEN_CPUFEATURE(CLWB,  5*32+24) /*A  CLWB instruction */
+XEN_CPUFEATURE(AVX512PF,  5*32+26) /*A  AVX-512 Prefetch Instruc

[Xen-devel] [PATCH v4] x86/cpuid: AVX-512 Feature Detection

2016-06-29 Thread Luwei Kang
AVX-512 is an extention of AVX2. Its spec can be found at:
https://software.intel.com/sites/default/files/managed/b4/3a/319433-024.pdf
This patch detects AVX-512 features by CPUID.

Signed-off-by: Luwei Kang 
---
[V4]:
Update the description about features dependency.
[V3]:
Adjust dependencies between features.
[V2]:
1.get max xstate_size from each bit.
2.change get cpuid function parameter from 0x07 to 7.
3.add dependencies between features in xen/tools/gen-cpuid.py.
4.split the cpuid call just like the way the hvm_cpuid() side works.
---
 xen/arch/x86/hvm/hvm.c  | 14 ++
 xen/arch/x86/traps.c| 22 +-
 xen/include/public/arch-x86/cpufeatureset.h |  9 +
 xen/tools/gen-cpuid.py  | 11 +++
 4 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index c89ab6e..7696b1e 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -3474,6 +3474,20 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, 
unsigned int *ebx,
   xstate_sizes[_XSTATE_BNDCSR]);
 }
 
+if ( _ebx & cpufeat_mask(X86_FEATURE_AVX512F) )
+{
+xfeature_mask |= XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM;
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_OPMASK] +
+  xstate_sizes[_XSTATE_OPMASK]);
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_ZMM] +
+  xstate_sizes[_XSTATE_ZMM]);
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_HI_ZMM] +
+  xstate_sizes[_XSTATE_HI_ZMM]);
+}
+
 if ( _ecx & cpufeat_mask(X86_FEATURE_PKU) )
 {
 xfeature_mask |= XSTATE_PKRU;
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 767d0b0..8fb697b 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -975,7 +975,7 @@ void pv_cpuid(struct cpu_user_regs *regs)
 
 switch ( leaf )
 {
-uint32_t tmp, _ecx;
+uint32_t tmp, _ecx, _ebx;
 
 case 0x0001:
 c &= pv_featureset[FEATURESET_1c];
@@ -1157,6 +1157,26 @@ void pv_cpuid(struct cpu_user_regs *regs)
xstate_sizes[_XSTATE_YMM]);
 }
 
+if ( !is_control_domain(currd) && !is_hardware_domain(currd) )
+domain_cpuid(currd, 7, 0, &tmp, &_ebx, &tmp, &tmp);
+else
+cpuid_count(7, 0, &tmp, &_ebx, &tmp, &tmp);
+_ebx &= pv_featureset[FEATURESET_7b0];
+
+if ( _ebx & cpufeat_mask(X86_FEATURE_AVX512F) )
+{
+xfeature_mask |= XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM;
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_OPMASK] +
+  xstate_sizes[_XSTATE_OPMASK]);
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_ZMM] +
+  xstate_sizes[_XSTATE_ZMM]);
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_HI_ZMM] +
+  xstate_sizes[_XSTATE_HI_ZMM]);
+}
+
 a = (uint32_t)xfeature_mask;
 d = (uint32_t)(xfeature_mask >> 32);
 c = xstate_size;
diff --git a/xen/include/public/arch-x86/cpufeatureset.h 
b/xen/include/public/arch-x86/cpufeatureset.h
index 39acf8c..9320c9e 100644
--- a/xen/include/public/arch-x86/cpufeatureset.h
+++ b/xen/include/public/arch-x86/cpufeatureset.h
@@ -206,15 +206,24 @@ XEN_CPUFEATURE(PQM,   5*32+12) /*   Platform QoS 
Monitoring */
 XEN_CPUFEATURE(NO_FPU_SEL,5*32+13) /*!  FPU CS/DS stored as zero */
 XEN_CPUFEATURE(MPX,   5*32+14) /*S  Memory Protection Extensions */
 XEN_CPUFEATURE(PQE,   5*32+15) /*   Platform QoS Enforcement */
+XEN_CPUFEATURE(AVX512F,   5*32+16) /*A  AVX-512 Foundation Instructions */
+XEN_CPUFEATURE(AVX512DQ,  5*32+17) /*A  AVX-512 Doubleword & Quadword 
Instrs */
 XEN_CPUFEATURE(RDSEED,5*32+18) /*A  RDSEED instruction */
 XEN_CPUFEATURE(ADX,   5*32+19) /*A  ADCX, ADOX instructions */
 XEN_CPUFEATURE(SMAP,  5*32+20) /*S  Supervisor Mode Access Prevention 
*/
+XEN_CPUFEATURE(AVX512IFMA,5*32+21) /*A  AVX-512 Integer Fused Multiply Add 
*/
 XEN_CPUFEATURE(CLFLUSHOPT,5*32+23) /*A  CLFLUSHOPT instruction */
 XEN_CPUFEATURE(CLWB,  5*32+24) /*A  CLWB instruction */
+XEN_CPUFEATURE(AVX512PF,  5*32+26) /*A  AVX-512 Prefetch Instructions */
+XEN_CPUFEATURE(AVX512ER,  5*32+27) /*A  AVX-512 E

[Xen-devel] [V3] x86/cpuid: AVX-512 Feature Detection

2016-06-29 Thread Luwei Kang
AVX-512 is an extention of AVX2. Its spec can be found at:
https://software.intel.com/sites/default/files/managed/b4/3a/319433-024.pdf
This patch detects AVX-512 features by CPUID.

Signed-off-by: Luwei Kang 
---
[V3]
1.adjust dependencies between features.
[V2]
1.one per bit, change from
> + xstate_size = max(xstate_size,
> + xstate_offsets[_XSTATE_HI_ZMM] +
> + xstate_sizes[_XSTATE_HI_ZMM]);
  to
xstate_size = max(xstate_size,
  xstate_offsets[_XSTATE_OPMASK] +
  xstate_sizes[_XSTATE_OPMASK]);
xstate_size = max(xstate_size,
  xstate_offsets[_XSTATE_ZMM] +
  xstate_sizes[_XSTATE_ZMM]);
xstate_size = max(xstate_size,
  xstate_offsets[_XSTATE_HI_ZMM] +
  xstate_sizes[_XSTATE_HI_ZMM]);
2.change form
domain_cpuid(currd, 0x07, 0, &tmp, &_ebx, &tmp, &tmp);
  to
domain_cpuid(currd, 7, 0, &tmp, &_ebx, &tmp, &tmp);
3.add dependencies between features in xen/tools/gen-cpuid.py
4.split the cpuid call just like the way the hvm_cpuid() side works.

 xen/arch/x86/hvm/hvm.c  | 14 ++
 xen/arch/x86/traps.c| 22 +-
 xen/include/public/arch-x86/cpufeatureset.h |  9 +
 xen/tools/gen-cpuid.py  | 11 +++
 4 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index c89ab6e..7696b1e 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -3474,6 +3474,20 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, 
unsigned int *ebx,
   xstate_sizes[_XSTATE_BNDCSR]);
 }
 
+if ( _ebx & cpufeat_mask(X86_FEATURE_AVX512F) )
+{
+xfeature_mask |= XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM;
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_OPMASK] +
+  xstate_sizes[_XSTATE_OPMASK]);
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_ZMM] +
+  xstate_sizes[_XSTATE_ZMM]);
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_HI_ZMM] +
+  xstate_sizes[_XSTATE_HI_ZMM]);
+}
+
 if ( _ecx & cpufeat_mask(X86_FEATURE_PKU) )
 {
 xfeature_mask |= XSTATE_PKRU;
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 767d0b0..8fb697b 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -975,7 +975,7 @@ void pv_cpuid(struct cpu_user_regs *regs)
 
 switch ( leaf )
 {
-uint32_t tmp, _ecx;
+uint32_t tmp, _ecx, _ebx;
 
 case 0x0001:
 c &= pv_featureset[FEATURESET_1c];
@@ -1157,6 +1157,26 @@ void pv_cpuid(struct cpu_user_regs *regs)
xstate_sizes[_XSTATE_YMM]);
 }
 
+if ( !is_control_domain(currd) && !is_hardware_domain(currd) )
+domain_cpuid(currd, 7, 0, &tmp, &_ebx, &tmp, &tmp);
+else
+cpuid_count(7, 0, &tmp, &_ebx, &tmp, &tmp);
+_ebx &= pv_featureset[FEATURESET_7b0];
+
+if ( _ebx & cpufeat_mask(X86_FEATURE_AVX512F) )
+{
+xfeature_mask |= XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM;
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_OPMASK] +
+  xstate_sizes[_XSTATE_OPMASK]);
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_ZMM] +
+  xstate_sizes[_XSTATE_ZMM]);
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_HI_ZMM] +
+  xstate_sizes[_XSTATE_HI_ZMM]);
+}
+
 a = (uint32_t)xfeature_mask;
 d = (uint32_t)(xfeature_mask >> 32);
 c = xstate_size;
diff --git a/xen/include/public/arch-x86/cpufeatureset.h 
b/xen/include/public/arch-x86/cpufeatureset.h
index 39acf8c..9320c9e 100644
--- a/xen/include/public/arch-x86/cpufeatureset.h
+++ b/xen/include/public/arch-x86/cpufeatureset.h
@@ -206,15 +206,24 @@ XEN_CPUFEATURE(PQM,   5*32+12) /*   Platform QoS 
Monitoring */
 XEN_CPUFEATURE(NO_FPU_SEL,5*32+13) /*!  FPU CS/DS stored as zero */
 XEN_CPUFEATURE(MPX,   5*32+14) /*S  Memory Protection Extensions */
 XEN_CPUFEATURE(PQE,   5*32+15) /*   Platform QoS Enforcement */
+XEN_CPUFEATURE(AVX512F,   5*32+16) /*A  AVX-512 Foundation Instructions */
+XEN_CPUFEATURE(AVX512

[Xen-devel] [PATCH] x86/cpuid: AVX-512 Feature Detection

2016-06-28 Thread Luwei Kang
AVX-512 is an extention of AVX2. Its spec can be found at:
https://software.intel.com/sites/default/files/managed/b4/3a/319433-024.pdf
This patch detects AVX-512 features by CPUID.

Signed-off-by: Luwei Kang 
---
 xen/arch/x86/hvm/hvm.c  | 14 ++
 xen/arch/x86/traps.c| 22 +-
 xen/include/public/arch-x86/cpufeatureset.h |  9 +
 xen/tools/gen-cpuid.py  |  4 
 4 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index c89ab6e..7696b1e 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -3474,6 +3474,20 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, 
unsigned int *ebx,
   xstate_sizes[_XSTATE_BNDCSR]);
 }
 
+if ( _ebx & cpufeat_mask(X86_FEATURE_AVX512F) )
+{
+xfeature_mask |= XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM;
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_OPMASK] +
+  xstate_sizes[_XSTATE_OPMASK]);
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_ZMM] +
+  xstate_sizes[_XSTATE_ZMM]);
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_HI_ZMM] +
+  xstate_sizes[_XSTATE_HI_ZMM]);
+}
+
 if ( _ecx & cpufeat_mask(X86_FEATURE_PKU) )
 {
 xfeature_mask |= XSTATE_PKRU;
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 767d0b0..8fb697b 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -975,7 +975,7 @@ void pv_cpuid(struct cpu_user_regs *regs)
 
 switch ( leaf )
 {
-uint32_t tmp, _ecx;
+uint32_t tmp, _ecx, _ebx;
 
 case 0x0001:
 c &= pv_featureset[FEATURESET_1c];
@@ -1157,6 +1157,26 @@ void pv_cpuid(struct cpu_user_regs *regs)
xstate_sizes[_XSTATE_YMM]);
 }
 
+if ( !is_control_domain(currd) && !is_hardware_domain(currd) )
+domain_cpuid(currd, 7, 0, &tmp, &_ebx, &tmp, &tmp);
+else
+cpuid_count(7, 0, &tmp, &_ebx, &tmp, &tmp);
+_ebx &= pv_featureset[FEATURESET_7b0];
+
+if ( _ebx & cpufeat_mask(X86_FEATURE_AVX512F) )
+{
+xfeature_mask |= XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM;
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_OPMASK] +
+  xstate_sizes[_XSTATE_OPMASK]);
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_ZMM] +
+  xstate_sizes[_XSTATE_ZMM]);
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_HI_ZMM] +
+  xstate_sizes[_XSTATE_HI_ZMM]);
+}
+
 a = (uint32_t)xfeature_mask;
 d = (uint32_t)(xfeature_mask >> 32);
 c = xstate_size;
diff --git a/xen/include/public/arch-x86/cpufeatureset.h 
b/xen/include/public/arch-x86/cpufeatureset.h
index 39acf8c..9320c9e 100644
--- a/xen/include/public/arch-x86/cpufeatureset.h
+++ b/xen/include/public/arch-x86/cpufeatureset.h
@@ -206,15 +206,24 @@ XEN_CPUFEATURE(PQM,   5*32+12) /*   Platform QoS 
Monitoring */
 XEN_CPUFEATURE(NO_FPU_SEL,5*32+13) /*!  FPU CS/DS stored as zero */
 XEN_CPUFEATURE(MPX,   5*32+14) /*S  Memory Protection Extensions */
 XEN_CPUFEATURE(PQE,   5*32+15) /*   Platform QoS Enforcement */
+XEN_CPUFEATURE(AVX512F,   5*32+16) /*A  AVX-512 Foundation Instructions */
+XEN_CPUFEATURE(AVX512DQ,  5*32+17) /*A  AVX-512 Doubleword & Quadword 
Instrs */
 XEN_CPUFEATURE(RDSEED,5*32+18) /*A  RDSEED instruction */
 XEN_CPUFEATURE(ADX,   5*32+19) /*A  ADCX, ADOX instructions */
 XEN_CPUFEATURE(SMAP,  5*32+20) /*S  Supervisor Mode Access Prevention 
*/
+XEN_CPUFEATURE(AVX512IFMA,5*32+21) /*A  AVX-512 Integer Fused Multiply Add 
*/
 XEN_CPUFEATURE(CLFLUSHOPT,5*32+23) /*A  CLFLUSHOPT instruction */
 XEN_CPUFEATURE(CLWB,  5*32+24) /*A  CLWB instruction */
+XEN_CPUFEATURE(AVX512PF,  5*32+26) /*A  AVX-512 Prefetch Instructions */
+XEN_CPUFEATURE(AVX512ER,  5*32+27) /*A  AVX-512 Exponent & Reciprocal 
Instrs */
+XEN_CPUFEATURE(AVX512CD,  5*32+28) /*A  AVX-512 Conflict Detection Instrs 
*/
 XEN_CPUFEATURE(SHA,   5*32+29) /*A  SHA1 & SHA256 instructions */
+XEN_CPUFEATURE(AVX512BW,  5*32+30) /*A  AVX-512 Byte and Word Instructions 
*/
+XEN_CPUFEATURE(AVX512VL,  5*32+31) /*A  AVX-512 Vector L

[Xen-devel] [PATCH] x86/cpuid: AVX-512 Feature Detection

2016-06-28 Thread Luwei Kang
AVX-512 is an extention of AVX2. Its spec can be found at:
https://software.intel.com/sites/default/files/managed/b4/3a/319433-024.pdf
This patch detects AVX-512 features by CPUID.

Signed-off-by: Luwei Kang 
---
 xen/arch/x86/hvm/hvm.c  | 14 ++
 xen/arch/x86/traps.c| 24 +++-
 xen/include/public/arch-x86/cpufeatureset.h |  9 +
 xen/tools/gen-cpuid.py  |  4 
 4 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index c89ab6e..7696b1e 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -3474,6 +3474,20 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, 
unsigned int *ebx,
   xstate_sizes[_XSTATE_BNDCSR]);
 }
 
+if ( _ebx & cpufeat_mask(X86_FEATURE_AVX512F) )
+{
+xfeature_mask |= XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM;
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_OPMASK] +
+  xstate_sizes[_XSTATE_OPMASK]);
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_ZMM] +
+  xstate_sizes[_XSTATE_ZMM]);
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_HI_ZMM] +
+  xstate_sizes[_XSTATE_HI_ZMM]);
+}
+
 if ( _ecx & cpufeat_mask(X86_FEATURE_PKU) )
 {
 xfeature_mask |= XSTATE_PKRU;
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 767d0b0..a190103 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -975,7 +975,7 @@ void pv_cpuid(struct cpu_user_regs *regs)
 
 switch ( leaf )
 {
-uint32_t tmp, _ecx;
+uint32_t tmp, _ecx, _ebx;
 
 case 0x0001:
 c &= pv_featureset[FEATURESET_1c];
@@ -1139,6 +1139,7 @@ void pv_cpuid(struct cpu_user_regs *regs)
 domain_cpuid(currd, 1, 0, &tmp, &tmp, &_ecx, &tmp);
 else
 _ecx = cpuid_ecx(1);
+
 _ecx &= pv_featureset[FEATURESET_1c];
 
 if ( !(_ecx & cpufeat_mask(X86_FEATURE_XSAVE)) || subleaf >= 63 )
@@ -1157,6 +1158,27 @@ void pv_cpuid(struct cpu_user_regs *regs)
xstate_sizes[_XSTATE_YMM]);
 }
 
+if ( !is_control_domain(currd) && !is_hardware_domain(currd) )
+domain_cpuid(currd, 7, 0, &tmp, &_ebx, &tmp, &tmp);
+else
+cpuid_count(7, 0, &tmp, &_ebx, &tmp, &tmp);
+
+_ebx &= pv_featureset[FEATURESET_7b0];
+
+if ( _ebx & cpufeat_mask(X86_FEATURE_AVX512F) )
+{
+xfeature_mask |= XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM;
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_OPMASK] +
+  xstate_sizes[_XSTATE_OPMASK]);
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_ZMM] +
+  xstate_sizes[_XSTATE_ZMM]);
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_HI_ZMM] +
+  xstate_sizes[_XSTATE_HI_ZMM]);
+}
+
 a = (uint32_t)xfeature_mask;
 d = (uint32_t)(xfeature_mask >> 32);
 c = xstate_size;
diff --git a/xen/include/public/arch-x86/cpufeatureset.h 
b/xen/include/public/arch-x86/cpufeatureset.h
index 39acf8c..9320c9e 100644
--- a/xen/include/public/arch-x86/cpufeatureset.h
+++ b/xen/include/public/arch-x86/cpufeatureset.h
@@ -206,15 +206,24 @@ XEN_CPUFEATURE(PQM,   5*32+12) /*   Platform QoS 
Monitoring */
 XEN_CPUFEATURE(NO_FPU_SEL,5*32+13) /*!  FPU CS/DS stored as zero */
 XEN_CPUFEATURE(MPX,   5*32+14) /*S  Memory Protection Extensions */
 XEN_CPUFEATURE(PQE,   5*32+15) /*   Platform QoS Enforcement */
+XEN_CPUFEATURE(AVX512F,   5*32+16) /*A  AVX-512 Foundation Instructions */
+XEN_CPUFEATURE(AVX512DQ,  5*32+17) /*A  AVX-512 Doubleword & Quadword 
Instrs */
 XEN_CPUFEATURE(RDSEED,5*32+18) /*A  RDSEED instruction */
 XEN_CPUFEATURE(ADX,   5*32+19) /*A  ADCX, ADOX instructions */
 XEN_CPUFEATURE(SMAP,  5*32+20) /*S  Supervisor Mode Access Prevention 
*/
+XEN_CPUFEATURE(AVX512IFMA,5*32+21) /*A  AVX-512 Integer Fused Multiply Add 
*/
 XEN_CPUFEATURE(CLFLUSHOPT,5*32+23) /*A  CLFLUSHOPT instruction */
 XEN_CPUFEATURE(CLWB,  5*32+24) /*A  CLWB instruction */
+XEN_CPUFEATURE(AVX512PF,  5*32+26) /*A  AVX-512 Prefetch Instructions */
+XEN_CPUFEATURE(AVX512ER,  5*32+27) /*A  AVX-512 Exponen

[Xen-devel] [PATCH] x86/cpuid: AVX-512 Feature Detection

2016-06-27 Thread Luwei Kang
AVX-512 is an extention of AVX2. Its spec can be found at:
https://software.intel.com/sites/default/files/managed/b4/3a/319433-024.pdf
This patch detects AVX-512 features by CPUID.

Signed-off-by: Luwei Kang 
---
 xen/arch/x86/hvm/hvm.c  |  8 
 xen/arch/x86/traps.c| 17 -
 xen/include/public/arch-x86/cpufeatureset.h |  9 +
 3 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index c89ab6e..693afd5 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -3474,6 +3474,14 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, 
unsigned int *ebx,
   xstate_sizes[_XSTATE_BNDCSR]);
 }
 
+if ( _ebx & cpufeat_mask(X86_FEATURE_AVX512F) )
+{
+xfeature_mask |= XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM;
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_HI_ZMM] +
+  xstate_sizes[_XSTATE_HI_ZMM]);
+}
+
 if ( _ecx & cpufeat_mask(X86_FEATURE_PKU) )
 {
 xfeature_mask |= XSTATE_PKRU;
diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 767d0b0..1c75e93 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -975,7 +975,7 @@ void pv_cpuid(struct cpu_user_regs *regs)
 
 switch ( leaf )
 {
-uint32_t tmp, _ecx;
+uint32_t tmp, _ecx, _ebx;
 
 case 0x0001:
 c &= pv_featureset[FEATURESET_1c];
@@ -1136,9 +1136,16 @@ void pv_cpuid(struct cpu_user_regs *regs)
 case XSTATE_CPUID:
 
 if ( !is_control_domain(currd) && !is_hardware_domain(currd) )
+{
 domain_cpuid(currd, 1, 0, &tmp, &tmp, &_ecx, &tmp);
+domain_cpuid(currd, 0x07, 0, &tmp, &_ebx, &tmp, &tmp);
+}
 else
+{
 _ecx = cpuid_ecx(1);
+cpuid_count(0x07, 0, &tmp, &_ebx, &tmp, &tmp);
+}
+
 _ecx &= pv_featureset[FEATURESET_1c];
 
 if ( !(_ecx & cpufeat_mask(X86_FEATURE_XSAVE)) || subleaf >= 63 )
@@ -1157,6 +1164,14 @@ void pv_cpuid(struct cpu_user_regs *regs)
xstate_sizes[_XSTATE_YMM]);
 }
 
+if ( _ebx & cpufeat_mask(X86_FEATURE_AVX512F) )
+{
+xfeature_mask |= XSTATE_OPMASK | XSTATE_ZMM | XSTATE_HI_ZMM;
+xstate_size = max(xstate_size,
+  xstate_offsets[_XSTATE_HI_ZMM] +
+  xstate_sizes[_XSTATE_HI_ZMM]);
+}
+
 a = (uint32_t)xfeature_mask;
 d = (uint32_t)(xfeature_mask >> 32);
 c = xstate_size;
diff --git a/xen/include/public/arch-x86/cpufeatureset.h 
b/xen/include/public/arch-x86/cpufeatureset.h
index 39acf8c..9320c9e 100644
--- a/xen/include/public/arch-x86/cpufeatureset.h
+++ b/xen/include/public/arch-x86/cpufeatureset.h
@@ -206,15 +206,24 @@ XEN_CPUFEATURE(PQM,   5*32+12) /*   Platform QoS 
Monitoring */
 XEN_CPUFEATURE(NO_FPU_SEL,5*32+13) /*!  FPU CS/DS stored as zero */
 XEN_CPUFEATURE(MPX,   5*32+14) /*S  Memory Protection Extensions */
 XEN_CPUFEATURE(PQE,   5*32+15) /*   Platform QoS Enforcement */
+XEN_CPUFEATURE(AVX512F,   5*32+16) /*A  AVX-512 Foundation Instructions */
+XEN_CPUFEATURE(AVX512DQ,  5*32+17) /*A  AVX-512 Doubleword & Quadword 
Instrs */
 XEN_CPUFEATURE(RDSEED,5*32+18) /*A  RDSEED instruction */
 XEN_CPUFEATURE(ADX,   5*32+19) /*A  ADCX, ADOX instructions */
 XEN_CPUFEATURE(SMAP,  5*32+20) /*S  Supervisor Mode Access Prevention 
*/
+XEN_CPUFEATURE(AVX512IFMA,5*32+21) /*A  AVX-512 Integer Fused Multiply Add 
*/
 XEN_CPUFEATURE(CLFLUSHOPT,5*32+23) /*A  CLFLUSHOPT instruction */
 XEN_CPUFEATURE(CLWB,  5*32+24) /*A  CLWB instruction */
+XEN_CPUFEATURE(AVX512PF,  5*32+26) /*A  AVX-512 Prefetch Instructions */
+XEN_CPUFEATURE(AVX512ER,  5*32+27) /*A  AVX-512 Exponent & Reciprocal 
Instrs */
+XEN_CPUFEATURE(AVX512CD,  5*32+28) /*A  AVX-512 Conflict Detection Instrs 
*/
 XEN_CPUFEATURE(SHA,   5*32+29) /*A  SHA1 & SHA256 instructions */
+XEN_CPUFEATURE(AVX512BW,  5*32+30) /*A  AVX-512 Byte and Word Instructions 
*/
+XEN_CPUFEATURE(AVX512VL,  5*32+31) /*A  AVX-512 Vector Length Extensions */
 
 /* Intel-defined CPU features, CPUID level 0x0007:0.ecx, word 6 */
 XEN_CPUFEATURE(PREFETCHWT1,   6*32+ 0) /*A  PREFETCHWT1 instruction */
+XEN_CPUFEATURE(AVX512VBMI,6*32+ 1) /*A  AVX-512 Vector Byte Manipulation 
Instrs */
 XEN_CPUFEATURE(PKU,   6*32+ 3) /*H  Protection Keys for Userspace */
 XEN_CPUFEATURE(OSPKE, 6*32+ 4) /*!  OS Protection Keys Enable */
 
-- 
2.7.4


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


[Xen-devel] [PATCH] x86/cpuid: fix dom0 crash on skylake machine

2016-05-31 Thread Luwei Kang
CPUID.0XD.0X0.EAX is from machine value for dom0, and dom0 kernel will xsetbv
with xfeatures_mask that is from CPUID.0XD.0X0.EAX, but handle_xsetbv has
ingored XSTATE_PKRU with hardware protection fault emulation, so dom0 kernel
will crash on skylake machine with PKRU support.

Signed-off-by: Luwei Kang 
---
 xen/arch/x86/traps.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index 1ef8401..5e72e44 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -1100,6 +1100,9 @@ void pv_cpuid(struct cpu_user_regs *regs)
  */
 if ( !is_control_domain(currd) && !is_hardware_domain(currd) )
 cpuid_count(leaf, subleaf, &tmp, &b, &tmp, &tmp);
+
+/* PV is not supported by XSTATE_PKRU. */
+a &= ~XSTATE_PKRU;
 break;
 }
 
-- 
2.7.4


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