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

[Xen-devel] [PATCH v2 06/10] x86: Introduce a new function to get capability of Intel PT



Introduce a new function to check if a specific capability
of Intel Processor Trace is exists.

Signed-off-by: Luwei Kang <luwei.kang@xxxxxxxxx>
---
 xen/arch/x86/cpu/ipt.c    | 63 +++++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-x86/ipt.h | 19 ++++++++++++++
 2 files changed, 82 insertions(+)

diff --git a/xen/arch/x86/cpu/ipt.c b/xen/arch/x86/cpu/ipt.c
index b81a155..977a3d7 100644
--- a/xen/arch/x86/cpu/ipt.c
+++ b/xen/arch/x86/cpu/ipt.c
@@ -25,11 +25,74 @@
 #include <asm/ipt.h>
 #include <asm/msr.h>
 
+#define EAX 0
+#define ECX 1
+#define EDX 2
+#define EBX 3
+#define CPUID_REGS_NUM   4 /* number of regsters (eax, ebx, ecx, edx) */
+
+#define BIT(nr)                 (1UL << (nr))
+
 /* ipt: Flag to enable Intel Processor Trace (default off). */
 unsigned int __read_mostly ipt_mode = IPT_MODE_OFF;
 static int parse_ipt_params(const char *str);
 custom_param("ipt", parse_ipt_params);
 
+#define IPT_CAP(_n, _l, _r, _m)                               \
+    [IPT_CAP_ ## _n] = { .name = __stringify(_n), .leaf = _l, \
+        .reg = _r, .mask = _m }
+
+static struct ipt_cap_desc {
+    const char    *name;
+    unsigned int  leaf;
+    unsigned char reg;
+    unsigned int  mask;
+} ipt_caps[] = {
+    IPT_CAP(max_subleaf,            0, EAX, 0xffffffff),
+    IPT_CAP(cr3_filter,             0, EBX, BIT(0)),
+    IPT_CAP(psb_cyc,                0, EBX, BIT(1)),
+    IPT_CAP(ip_filter,              0, EBX, BIT(2)),
+    IPT_CAP(mtc,                    0, EBX, BIT(3)),
+    IPT_CAP(ptwrite,                0, EBX, BIT(4)),
+    IPT_CAP(power_event,            0, EBX, BIT(5)),
+    IPT_CAP(topa_output,            0, ECX, BIT(0)),
+    IPT_CAP(topa_multi_entry,       0, ECX, BIT(1)),
+    IPT_CAP(single_range_output,    0, ECX, BIT(2)),
+    IPT_CAP(output_subsys,          0, ECX, BIT(3)),
+    IPT_CAP(payloads_lip,           0, ECX, BIT(31)),
+    IPT_CAP(addr_range,             1, EAX, 0x7),
+    IPT_CAP(mtc_period,             1, EAX, 0xffff0000),
+    IPT_CAP(cycle_threshold,        1, EBX, 0xffff),
+    IPT_CAP(psb_freq,               1, EBX, 0xffff0000),
+};
+
+static unsigned int ipt_cap(const struct cpuid_leaf *cpuid_ipt, enum ipt_cap 
cap)
+{
+    const struct ipt_cap_desc *cd = &ipt_caps[cap];
+    unsigned int shift = ffs(cd->mask) - 1;
+    unsigned int val = 0;
+
+    cpuid_ipt += cd->leaf;
+
+    switch ( cd->reg )
+    {
+    case EAX:
+        val = cpuid_ipt->a;
+        break;
+    case EBX:
+        val = cpuid_ipt->b;
+        break;
+    case ECX:
+        val = cpuid_ipt->c;
+        break;
+    case EDX:
+        val = cpuid_ipt->d;
+        break;
+    }
+
+    return (val & cd->mask) >> shift;
+}
+
 static int __init parse_ipt_params(const char *str)
 {
     if ( !strcmp("guest", str) )
diff --git a/xen/include/asm-x86/ipt.h b/xen/include/asm-x86/ipt.h
index a69f049..422f46a 100644
--- a/xen/include/asm-x86/ipt.h
+++ b/xen/include/asm-x86/ipt.h
@@ -31,6 +31,25 @@
 
 extern unsigned int ipt_mode;
 
+enum ipt_cap {
+    IPT_CAP_max_subleaf = 0,
+    IPT_CAP_cr3_filter,
+    IPT_CAP_psb_cyc,
+    IPT_CAP_ip_filter,
+    IPT_CAP_mtc,
+    IPT_CAP_ptwrite,
+    IPT_CAP_power_event,
+    IPT_CAP_topa_output,
+    IPT_CAP_topa_multi_entry,
+    IPT_CAP_single_range_output,
+    IPT_CAP_output_subsys,
+    IPT_CAP_payloads_lip,
+    IPT_CAP_addr_range,
+    IPT_CAP_mtc_period,
+    IPT_CAP_cycle_threshold,
+    IPT_CAP_psb_freq,
+};
+
 struct ipt_ctx {
     uint64_t ctl;
     uint64_t status;
-- 
1.8.3.1


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

 


Rackspace

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