tools/perf/arch/x86/tests/intel-pt-test.c

Source file repositories/reference/linux-study-clean/tools/perf/arch/x86/tests/intel-pt-test.c

File Facts

System
Linux kernel
Corpus path
tools/perf/arch/x86/tests/intel-pt-test.c
Extension
.c
Size
17018 bytes
Lines
470
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct cpuid_result {
	union {
		struct {
			unsigned int eax;
			unsigned int ebx;
			unsigned int ecx;
			unsigned int edx;
		};
		unsigned int reg[CPUID_REG_CNT];
	};
};

struct pt_caps {
	struct cpuid_result subleaf[INTEL_PT_SUBLEAF_CNT];
};

static int get_pt_caps(int cpu, struct pt_caps *caps)
{
	struct cpuid_result r;
	int i;

	if (setaffinity(cpu))
		return -1;

	memset(caps, 0, sizeof(*caps));

	for (i = 0; i < INTEL_PT_SUBLEAF_CNT; i++) {
		cpuid(20, i, &r.eax, &r.ebx, &r.ecx, &r.edx);
		pr_debug("CPU %d CPUID leaf 20 subleaf %d\n", cpu, i);
		pr_debug("eax = 0x%08x\n", r.eax);
		pr_debug("ebx = 0x%08x\n", r.ebx);
		pr_debug("ecx = 0x%08x\n", r.ecx);
		pr_debug("edx = 0x%08x\n", r.edx);
		caps->subleaf[i] = r;
	}

	return 0;
}

static bool is_hybrid(void)
{
	unsigned int eax, ebx, ecx, edx = 0;
	bool result;

	cpuid(7, 0, &eax, &ebx, &ecx, &edx);
	result = edx & BIT(15);
	pr_debug("Is %shybrid : CPUID leaf 7 subleaf 0 edx %#x (bit-15 indicates hybrid)\n",
		 result ? "" : "not ", edx);
	return result;
}

static int compare_caps(int cpu, struct pt_caps *caps, struct pt_caps *caps0)
{
	struct pt_caps mask = { /* Mask of bits to check*/
		.subleaf = {
			[0] = {
				.ebx = GENMASK(8, 0),
				.ecx = GENMASK(3, 0),
			},
			[1] = {
				.eax = GENMASK(31, 16),
				.ebx = GENMASK(31, 0),
			}
		}
	};
	unsigned int m, reg, reg0;
	int ret = 0;
	int i, j;

	for (i = 0; i < INTEL_PT_SUBLEAF_CNT; i++) {
		for (j = 0; j < CPUID_REG_CNT; j++) {
			m = mask.subleaf[i].reg[j];
			reg = m & caps->subleaf[i].reg[j];
			reg0 = m & caps0->subleaf[i].reg[j];
			if ((reg & reg0) != reg0) {
				pr_debug("CPU %d subleaf %d reg %d FAIL %#x vs %#x\n",
					 cpu, i, j, reg, reg0);
				ret = -1;
			}
		}
	}

	m = INTEL_PT_ADDR_FILT_CNT_MASK;
	reg = m & caps->subleaf[1].eax;
	reg0 = m & caps0->subleaf[1].eax;
	if (reg < reg0) {
		pr_debug("CPU %d subleaf 1 reg 0 FAIL address filter count %#x vs %#x\n",
			 cpu, reg, reg0);
		ret = -1;
	}

Annotation

Implementation Notes