[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 |