perf/smmuv3: Enable HiSilicon Erratum quirk
ANBZ: #11194 commit fda37f5b011d5c007e5b772a90e524cf6ed5dad0 openeuler driver inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I798Y2 CVE: NA ---------------------------------------------------------------------- Some HiSilicon SMMU PMCG suffers the erratum that the global PMU disable control sometimes fail to disable each used the counters. This will lead to error or inaccurate data since before we enable the counters the counter's still counting for the event used in last perf session. This patch tries to fix this by hardening the global disable process. Before disable the PMU, writing an invalid event type (0xff) to focibly stop the counters. Signed-off-by: Yicong Yang <yangyicong@hisilicon.com> Signed-off-by: Junhao He <hejunhao3@huawei.com> Signed-off-by: Min Li <gumi@linux.alibaba.com> Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com> Link: https://gitee.com/anolis/cloud-kernel/pulls/4243
This commit is contained in:
parent
40d77edddf
commit
791bd6a602
|
@ -1475,6 +1475,9 @@ static struct acpi_platform_list pmcg_plat_info[] __initdata = {
|
|||
/* HiSilicon Hip08 Platform */
|
||||
{"HISI ", "HIP08 ", 0, ACPI_SIG_IORT, greater_than_or_equal,
|
||||
"Erratum #162001800", IORT_SMMU_V3_PMCG_HISI_HIP08},
|
||||
/* HiSilicon Hip09 Platform */
|
||||
{"HISI ", "HIP09 ", 0, ACPI_SIG_IORT, greater_than_or_equal,
|
||||
"Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09},
|
||||
{"PTG ", "PTG01 ", 0, ACPI_SIG_IORT, greater_than_or_equal,
|
||||
"BABAPTG", IORT_SMMU_V3_PMCG_BABA_MPTG1},
|
||||
{ }
|
||||
|
|
|
@ -97,6 +97,8 @@
|
|||
|
||||
#define SMMU_PMCG_EVCNTR_RDONLY BIT(0)
|
||||
#define SMMU_PMCG_GLOBAL_FILTER_MANY_EVT BIT(1)
|
||||
#define SMMU_PMCG_DISABLE_HARDEN BIT(1)
|
||||
|
||||
static int cpuhp_state_num;
|
||||
|
||||
struct smmu_pmu {
|
||||
|
@ -140,10 +142,26 @@ static inline void smmu_pmu_enable(struct pmu *pmu)
|
|||
writel(SMMU_PMCG_CR_ENABLE, smmu_pmu->reg_base + SMMU_PMCG_CR);
|
||||
}
|
||||
|
||||
static inline void smmu_pmu_disable_harden(struct smmu_pmu *smmu_pmu)
|
||||
{
|
||||
unsigned int idx;
|
||||
|
||||
/*
|
||||
* The global disable of PMU sometimes fail to stop the counting.
|
||||
* Harden this by writing an invalid event type to each used counter
|
||||
* to forcibly stop counting.
|
||||
*/
|
||||
for_each_set_bit(idx, smmu_pmu->used_counters, smmu_pmu->num_counters)
|
||||
writel(0xffff, smmu_pmu->reg_base + SMMU_PMCG_EVTYPER(idx));
|
||||
}
|
||||
|
||||
static inline void smmu_pmu_disable(struct pmu *pmu)
|
||||
{
|
||||
struct smmu_pmu *smmu_pmu = to_smmu_pmu(pmu);
|
||||
|
||||
if (smmu_pmu->options & SMMU_PMCG_DISABLE_HARDEN)
|
||||
smmu_pmu_disable_harden(smmu_pmu);
|
||||
|
||||
writel(0, smmu_pmu->reg_base + SMMU_PMCG_CR);
|
||||
writel(0, smmu_pmu->reg_base + SMMU_PMCG_IRQ_CTRL);
|
||||
}
|
||||
|
@ -762,7 +780,10 @@ static void smmu_pmu_get_acpi_options(struct smmu_pmu *smmu_pmu)
|
|||
switch (model) {
|
||||
case IORT_SMMU_V3_PMCG_HISI_HIP08:
|
||||
/* HiSilicon Erratum 162001800 */
|
||||
smmu_pmu->options |= SMMU_PMCG_EVCNTR_RDONLY;
|
||||
smmu_pmu->options |= SMMU_PMCG_EVCNTR_RDONLY | SMMU_PMCG_DISABLE_HARDEN;
|
||||
break;
|
||||
case IORT_SMMU_V3_PMCG_HISI_HIP09:
|
||||
smmu_pmu->options |= SMMU_PMCG_DISABLE_HARDEN;
|
||||
break;
|
||||
|
||||
case IORT_SMMU_V3_PMCG_BABA_MPTG1:
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define IORT_SMMU_V3_PMCG_GENERIC 0x00000000 /* Generic SMMUv3 PMCG */
|
||||
#define IORT_SMMU_V3_PMCG_HISI_HIP08 0x00000001 /* HiSilicon HIP08 PMCG */
|
||||
#define IORT_SMMU_V3_PMCG_BABA_MPTG1 0x00000010 /* Alibaba PTG PMCG */
|
||||
#define IORT_SMMU_V3_PMCG_HISI_HIP09 0x00000002 /* HiSilicon HIP09 PMCG */
|
||||
|
||||
int iort_register_domain_token(int trans_id, phys_addr_t base,
|
||||
struct fwnode_handle *fw_node);
|
||||
|
|
Loading…
Reference in New Issue