Commit 25fd62f6 authored by leoliu-oc's avatar leoliu-oc
Browse files

perf/x86/zhaoxin/uncore: update KX-7000 support

zhaoxin inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/IA6M0X


CVE: NA

-------------------

1. Enhance perf kvm guest/host support to allow monitoring of either the
   host or guest independently.
2. Add architecture print information after successful loading of the
   KX7000 pmc core driver, indicating that the architecture of KX7000 is
   shijidadao.
3. Modify the KX8000 in the uncore driver to KX7000.
4. Add logic_op support for the KX7000 uncore.
5. For the KX7000 platform, it is necessary to configure the bit16
   (bsPMCDynamicEn_P) of msr1877h to 0 (previously it was defaulted to 1)
   during the PMC driver loading, so that the KX7000 PMC HIF module can
   operate normally.

Signed-off-by: default avatarleoliu-oc <leoliu-oc@zhaoxin.com>
parent fac11126
Loading
Loading
Loading
Loading
+70 −25
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@
 * Zhaoxin PerfMon, used on Lujiazui and later.
 */
static u64 zx_pmon_event_map[PERF_COUNT_HW_MAX] __read_mostly = {

	[PERF_COUNT_HW_CPU_CYCLES]		= 0x0082,
	[PERF_COUNT_HW_INSTRUCTIONS]		= 0x00c0,
	[PERF_COUNT_HW_BUS_CYCLES]		= 0x0083,
@@ -259,7 +258,9 @@ static void zhaoxin_pmu_disable_all(void)

static void zhaoxin_pmu_enable_all(int added)
{
	wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl);
	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);

	wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask);
}

static inline u64 zhaoxin_pmu_get_status(void)
@@ -286,13 +287,31 @@ static inline void zxc_pmu_ack_status(u64 ack)
	zhaoxin_pmu_disable_all();
}

static void zhaoxin_pmu_disable_fixed(struct hw_perf_event *hwc)
static inline void zhaoxin_set_masks(struct perf_event *event, int idx)
{
	int idx = hwc->idx - INTEL_PMC_IDX_FIXED;
	u64 ctrl_val, mask;
	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);

	mask = 0xfULL << (idx * 4);
	if (event->attr.exclude_host)
		__set_bit(idx, (unsigned long *)&cpuc->intel_ctrl_guest_mask);
	if (event->attr.exclude_guest)
		__set_bit(idx, (unsigned long *)&cpuc->intel_ctrl_host_mask);
}

static inline void zhaoxin_clear_masks(struct perf_event *event, int idx)
{
	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);

	__clear_bit(idx, (unsigned long *)&cpuc->intel_ctrl_guest_mask);
	__clear_bit(idx, (unsigned long *)&cpuc->intel_ctrl_host_mask);
}

static void zhaoxin_pmu_disable_fixed(struct perf_event *event)
{
	struct hw_perf_event *hwc = &event->hw;
	u64 ctrl_val, mask;
	int idx = hwc->idx;

	mask = 0xfULL << ((idx - INTEL_PMC_IDX_FIXED) * 4);
	rdmsrl(hwc->config_base, ctrl_val);
	ctrl_val &= ~mask;
	wrmsrl(hwc->config_base, ctrl_val);
@@ -301,19 +320,23 @@ static void zhaoxin_pmu_disable_fixed(struct hw_perf_event *hwc)
static void zhaoxin_pmu_disable_event(struct perf_event *event)
{
	struct hw_perf_event *hwc = &event->hw;
	int idx = hwc->idx;

	zhaoxin_clear_masks(event, idx);

	if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
		zhaoxin_pmu_disable_fixed(hwc);
		zhaoxin_pmu_disable_fixed(event);
		return;
	}

	x86_pmu_disable_event(event);
}

static void zhaoxin_pmu_enable_fixed(struct hw_perf_event *hwc)
static void zhaoxin_pmu_enable_fixed(struct perf_event *event)
{
	int idx = hwc->idx - INTEL_PMC_IDX_FIXED;
	u64 ctrl_val, bits, mask;
	struct hw_perf_event *hwc = &event->hw;
	u64 ctrl_val, mask, bits = 0;
	int idx = hwc->idx;

	/*
	 * Enable IRQ generation (0x8),
@@ -326,6 +349,7 @@ static void zhaoxin_pmu_enable_fixed(struct hw_perf_event *hwc)
	if (hwc->config & ARCH_PERFMON_EVENTSEL_OS)
		bits |= 0x1;

	idx -= INTEL_PMC_IDX_FIXED;
	bits <<= (idx * 4);
	mask = 0xfULL << (idx * 4);

@@ -338,9 +362,12 @@ static void zhaoxin_pmu_enable_fixed(struct hw_perf_event *hwc)
static void zhaoxin_pmu_enable_event(struct perf_event *event)
{
	struct hw_perf_event *hwc = &event->hw;
	int idx = hwc->idx;

	zhaoxin_set_masks(event, idx);

	if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
		zhaoxin_pmu_enable_fixed(hwc);
		zhaoxin_pmu_enable_fixed(event);
		return;
	}

@@ -456,6 +483,19 @@ static ssize_t zhaoxin_event_sysfs_show(char *page, u64 config)
	return x86_event_sysfs_show(page, config, event);
}

static struct perf_guest_switch_msr *zhaoxin_guest_get_msrs(int *nr, void *data)
{
	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
	struct perf_guest_switch_msr *arr = cpuc->guest_switch_msrs;

	arr[0].msr = MSR_CORE_PERF_GLOBAL_CTRL;
	arr[0].host = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask;
	arr[0].guest = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_host_mask;
	*nr = 1;

	return arr;
}

static const struct x86_pmu zhaoxin_pmu __initconst = {
	.name			= "zhaoxin",
	.handle_irq		= zhaoxin_pmu_handle_irq,
@@ -478,6 +518,8 @@ static const struct x86_pmu zhaoxin_pmu __initconst = {

	.format_attrs		= zx_arch_formats_attr,
	.events_sysfs_show	= zhaoxin_event_sysfs_show,

	.guest_get_msrs		= zhaoxin_guest_get_msrs,
};

static const struct { int id; char *name; } zx_arch_events_map[] __initconst = {
@@ -581,8 +623,8 @@ __init int zhaoxin_pmu_init(void)

			x86_pmu.event_constraints = wudaokou_event_constraints;

			zx_pmon_event_map[PERF_COUNT_HW_CACHE_REFERENCES]  = 0x0515,
			zx_pmon_event_map[PERF_COUNT_HW_CACHE_MISSES]      = 0x051a,
			zx_pmon_event_map[PERF_COUNT_HW_CACHE_REFERENCES] = 0x0515;
			zx_pmon_event_map[PERF_COUNT_HW_CACHE_MISSES] = 0x051a;

			zx_pmon_event_map[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x0700;
			zx_pmon_event_map[PERF_COUNT_HW_BRANCH_MISSES] = 0x0709;
@@ -595,8 +637,8 @@ __init int zhaoxin_pmu_init(void)

			x86_pmu.event_constraints = wudaokou_event_constraints;

			zx_pmon_event_map[PERF_COUNT_HW_CACHE_REFERENCES]  = 0x0515,
			zx_pmon_event_map[PERF_COUNT_HW_CACHE_MISSES]      = 0x051a,
			zx_pmon_event_map[PERF_COUNT_HW_CACHE_REFERENCES] = 0x0515;
			zx_pmon_event_map[PERF_COUNT_HW_CACHE_MISSES] = 0x051a;

			pr_cont("Lujiazui events, ");
			break;
@@ -616,6 +658,10 @@ __init int zhaoxin_pmu_init(void)

			if (boot_cpu_data.x86_model == 0x5b)
				pr_cont("Yongfeng events, ");

			if (boot_cpu_data.x86_model == 0x6b)
				pr_cont("Shijidadao events, ");

			break;
		default:
			return -ENODEV;
@@ -638,4 +684,3 @@ __init int zhaoxin_pmu_init(void)

	return 0;
}
+568 −521

File changed.

Preview size limit exceeded, changes collapsed.

+35 −52
Original line number Diff line number Diff line
@@ -10,9 +10,7 @@
#define ZHAOXIN_FAM7_KX5000		0x1b
#define ZHAOXIN_FAM7_KX6000		0x3b
#define ZHAOXIN_FAM7_KH40000		0x5b
#define ZHAOXIN_FAM7_KX8000		0x6b


#define ZHAOXIN_FAM7_KX7000		0x6b

#define UNCORE_PMU_NAME_LEN		32
#define UNCORE_PMU_HRTIMER_INTERVAL	(60LL * NSEC_PER_SEC)
@@ -135,8 +133,7 @@ struct hw_info {
	u64 active_state;
};

ssize_t zx_uncore_event_show(struct device *dev,
			  struct device_attribute *attr, char *buf);
ssize_t zx_uncore_event_show(struct device *dev, struct device_attribute *attr, char *buf);

#define ZHAOXIN_UNCORE_EVENT_DESC(_name, _config)			\
{									\
@@ -160,11 +157,9 @@ static inline bool uncore_pmc_fixed(int idx)
	return idx == UNCORE_PMC_IDX_FIXED;
}

static inline
unsigned int uncore_mmio_box_ctl(struct zhaoxin_uncore_box *box)
static inline unsigned int uncore_mmio_box_ctl(struct zhaoxin_uncore_box *box)
{
	return box->pmu->type->box_ctl +
	       box->pmu->type->mmio_offset * box->pmu->pmu_idx;
	return box->pmu->type->box_ctl + box->pmu->type->mmio_offset * box->pmu->pmu_idx;
}

static inline unsigned int uncore_pci_box_ctl(struct zhaoxin_uncore_box *box)
@@ -182,14 +177,12 @@ static inline unsigned int uncore_pci_fixed_ctr(struct zhaoxin_uncore_box *box)
	return box->pmu->type->fixed_ctr;
}

static inline
unsigned int uncore_pci_event_ctl(struct zhaoxin_uncore_box *box, int idx)
static inline unsigned int uncore_pci_event_ctl(struct zhaoxin_uncore_box *box, int idx)
{
	return idx * 4 + box->pmu->type->event_ctl;
}

static inline
unsigned int uncore_pci_perf_ctr(struct zhaoxin_uncore_box *box, int idx)
static inline unsigned int uncore_pci_perf_ctr(struct zhaoxin_uncore_box *box, int idx)
{
	if (!strncmp(box->pmu->type->name, "mc_", 3))
		return idx * 2 + box->pmu->type->perf_ctr;
@@ -225,24 +218,20 @@ static inline unsigned int uncore_msr_fixed_ctr(struct zhaoxin_uncore_box *box)
	return box->pmu->type->fixed_ctr + uncore_msr_box_offset(box);
}

static inline
unsigned int uncore_msr_event_ctl(struct zhaoxin_uncore_box *box, int idx)
static inline unsigned int uncore_msr_event_ctl(struct zhaoxin_uncore_box *box, int idx)
{
	return box->pmu->type->event_ctl +
		(box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) +
	return box->pmu->type->event_ctl + (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) +
	       uncore_msr_box_offset(box);
}

static inline
unsigned int uncore_msr_perf_ctr(struct zhaoxin_uncore_box *box, int idx)
static inline unsigned int uncore_msr_perf_ctr(struct zhaoxin_uncore_box *box, int idx)
{
	return box->pmu->type->perf_ctr +
		(box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) +
		uncore_msr_box_offset(box);
}

static inline
unsigned int uncore_fixed_ctl(struct zhaoxin_uncore_box *box)
static inline unsigned int uncore_fixed_ctl(struct zhaoxin_uncore_box *box)
{
	if (box->pci_dev)
		return uncore_pci_fixed_ctl(box);
@@ -250,8 +239,7 @@ unsigned int uncore_fixed_ctl(struct zhaoxin_uncore_box *box)
		return uncore_msr_fixed_ctl(box);
}

static inline
unsigned int uncore_fixed_ctr(struct zhaoxin_uncore_box *box)
static inline unsigned int uncore_fixed_ctr(struct zhaoxin_uncore_box *box)
{
	if (box->pci_dev)
		return uncore_pci_fixed_ctr(box);
@@ -259,17 +247,17 @@ unsigned int uncore_fixed_ctr(struct zhaoxin_uncore_box *box)
		return uncore_msr_fixed_ctr(box);
}

static inline
unsigned int uncore_event_ctl(struct zhaoxin_uncore_box *box, int idx)
{	if (box->pci_dev || box->io_addr)
static inline unsigned int uncore_event_ctl(struct zhaoxin_uncore_box *box, int idx)
{
	if (box->pci_dev || box->io_addr)
		return uncore_pci_event_ctl(box, idx);
	else
		return uncore_msr_event_ctl(box, idx);
}

static inline
unsigned int uncore_perf_ctr(struct zhaoxin_uncore_box *box, int idx)
{	if (box->pci_dev || box->io_addr)
static inline unsigned int uncore_perf_ctr(struct zhaoxin_uncore_box *box, int idx)
{
	if (box->pci_dev || box->io_addr)
		return uncore_pci_perf_ctr(box, idx);
	else
		return uncore_msr_perf_ctr(box, idx);
@@ -302,20 +290,17 @@ static inline void uncore_enable_box(struct zhaoxin_uncore_box *box)
		box->pmu->type->ops->enable_box(box);
}

static inline void uncore_disable_event(struct zhaoxin_uncore_box *box,
				struct perf_event *event)
static inline void uncore_disable_event(struct zhaoxin_uncore_box *box, struct perf_event *event)
{
	box->pmu->type->ops->disable_event(box, event);
}

static inline void uncore_enable_event(struct zhaoxin_uncore_box *box,
				struct perf_event *event)
static inline void uncore_enable_event(struct zhaoxin_uncore_box *box, struct perf_event *event)
{
	box->pmu->type->ops->enable_event(box, event);
}

static inline u64 uncore_read_counter(struct zhaoxin_uncore_box *box,
				struct perf_event *event)
static inline u64 uncore_read_counter(struct zhaoxin_uncore_box *box, struct perf_event *event)
{
	return box->pmu->type->ops->read_counter(box, event);
}
@@ -351,12 +336,10 @@ static inline struct zhaoxin_uncore_box *uncore_event_to_box(struct perf_event *
	return event->pmu_private;
}


static struct zhaoxin_uncore_box *uncore_pmu_to_box(struct zhaoxin_uncore_pmu *pmu, int cpu);
static u64 uncore_msr_read_counter(struct zhaoxin_uncore_box *box, struct perf_event *event);
static void uncore_mmio_exit_box(struct zhaoxin_uncore_box *box);
static u64 uncore_mmio_read_counter(struct zhaoxin_uncore_box *box,
			     struct perf_event *event);
static u64 uncore_mmio_read_counter(struct zhaoxin_uncore_box *box, struct perf_event *event);
static void uncore_pmu_start_hrtimer(struct zhaoxin_uncore_box *box);
static void uncore_pmu_cancel_hrtimer(struct zhaoxin_uncore_box *box);
static void uncore_pmu_event_start(struct perf_event *event, int flags);
@@ -365,7 +348,7 @@ static int uncore_pmu_event_add(struct perf_event *event, int flags);
static void uncore_pmu_event_del(struct perf_event *event, int flags);
static void uncore_pmu_event_read(struct perf_event *event);
static void uncore_perf_event_update(struct zhaoxin_uncore_box *box, struct perf_event *event);
struct event_constraint *
uncore_get_constraint(struct zhaoxin_uncore_box *box, struct perf_event *event);
struct event_constraint *uncore_get_constraint(struct zhaoxin_uncore_box *box,
					       struct perf_event *event);
void uncore_put_constraint(struct zhaoxin_uncore_box *box, struct perf_event *event);
u64 uncore_shared_reg_config(struct zhaoxin_uncore_box *box, int idx);