Skip to content

Commit 2895b90

Browse files
pavelvkozlovxxkent
authored andcommitted
ARCv3: add extra cluster presence check by read of CLUSTER_BUILD BCR
Read CLUSTER_BUILD BCR and check cluster presence before access to cluster performance counter registers. Prevent read/write of AUX cluster CLNR_ADDR and CLNR_DATA resisters if they don't exist. Fixes: f269da7 ("ARCv3: Perf cluster driver fix") Signed-off-by: Pavel Kozlov <[email protected]>
1 parent e656cb4 commit 2895b90

File tree

2 files changed

+24
-24
lines changed

2 files changed

+24
-24
lines changed

arch/arc/include/asm/perf_cluster.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@
1212
#define BIT(x) (1 << (x))
1313
#endif
1414

15-
#define CLNR_ADDR 0x640
16-
#define CLNR_DATA 0x641
17-
1815
#define SCM_AUX_CPCT_BUILD 0xC00
1916
#define SCM_AUX_CPCT_CC_NUM 0xC03
2017
#define SCM_AUX_CPCT_CC_NAME0 0xC04

arch/arc/kernel/perf_cluster.c

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <linux/percpu.h>
1717
#include <asm/arcregs.h>
1818
#include <asm/stacktrace.h>
19+
#include <asm/cluster.h>
1920
#include <asm/perf_cluster.h>
2021

2122

@@ -45,20 +46,20 @@ static void arc_cluster_pmu_read_reg(unsigned int reg, void *data)
4546
unsigned int val;
4647

4748
spin_lock_irqsave(&cln_prot_op_spinlock, flags);
48-
WRITE_AUX(CLNR_ADDR, reg);
49-
READ_BCR(CLNR_DATA, val);
49+
WRITE_AUX(ARC_REG_CLNR_ADDR, reg);
50+
READ_BCR(ARC_REG_CLNR_DATA, val);
5051
spin_unlock_irqrestore(&cln_prot_op_spinlock, flags);
51-
*(unsigned int *)data = val;
52+
*(unsigned int *)data = val;
5253
}
5354

5455
static void arc_cluster_pmu_write_reg(unsigned int reg, void *data)
5556
{
5657
unsigned long flags;
57-
unsigned int val = *(unsigned int *)data;
58+
unsigned int val = *(unsigned int *)data;
5859

5960
spin_lock_irqsave(&cln_prot_op_spinlock, flags);
60-
WRITE_AUX(CLNR_ADDR, reg);
61-
WRITE_AUX(CLNR_DATA, val);
61+
WRITE_AUX(ARC_REG_CLNR_ADDR, reg);
62+
WRITE_AUX(ARC_REG_CLNR_DATA, val);
6263
spin_unlock_irqrestore(&cln_prot_op_spinlock, flags);
6364
}
6465

@@ -702,9 +703,10 @@ static int arc_cluster_pmu_device_probe(struct platform_device *pdev)
702703
int ii;
703704
int has_interrupts = 0, irq = -1;
704705
int counter_size; /* in bits */
705-
int ncounters;
706-
int nevents;
706+
int ncounters;
707+
int nevents;
707708
u32 int_reg;
709+
struct bcr_clustv3_cfg cbcr;
708710
struct arc_cluster_cpu __percpu *pcpu;
709711
int ret;
710712

@@ -713,22 +715,23 @@ static int arc_cluster_pmu_device_probe(struct platform_device *pdev)
713715
return -ENODEV;
714716
#endif
715717

716-
if (!arc_cluster_pmu_is_present()){
717-
pr_err("Error! Cluster PCT module is not presented in the system.\n");
718-
return -ENODEV;
719-
}
718+
READ_BCR(ARC_REG_CLUSTER_BCR, cbcr);
719+
if (!cbcr.ver_maj || !arc_cluster_pmu_is_present()){
720+
pr_err("Cluster PCT module doesn't present in the system.\n");
721+
return -ENODEV;
722+
}
720723

721-
ncounters = arc_cluster_pmu_get_n_counters();
722-
if (!ncounters) {
723-
pr_err("Error! Cluster PCT module doesn't have counters.\n");
724-
return -EINVAL;
725-
}
724+
ncounters = arc_cluster_pmu_get_n_counters();
725+
if (!ncounters) {
726+
pr_err("Cluster PCT module doesn't have counters.\n");
727+
return -EINVAL;
728+
}
726729

727730
nevents = arc_cluster_pmu_get_events_number();
728-
if (!nevents) {
729-
pr_err("Error! Cluster PCT module doesn't have countable conditions.\n");
730-
return -EINVAL;
731-
}
731+
if (!nevents) {
732+
pr_err("Cluster PCT module doesn't have countable conditions.\n");
733+
return -EINVAL;
734+
}
732735

733736
arc_cluster_pmu = devm_kzalloc(&pdev->dev, sizeof(struct arc_cluster_pmu), GFP_KERNEL);
734737
if (!arc_cluster_pmu)

0 commit comments

Comments
 (0)