|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |