@@ -71,7 +71,8 @@ struct arm_pmu {
void (*disable)(struct perf_event *event);
int (*get_event_idx)(struct pmu_hw_events *hw_events,
struct perf_event *event);
- void (*clear_event_idx)(struct perf_event *event);
+ void (*clear_event_idx)(struct pmu_hw_events *hw_events,
+ struct perf_event *event);
int (*set_event_filter)(struct hw_perf_event *evt,
struct perf_event_attr *attr);
u32 (*read_counter)(struct perf_event *event);
@@ -208,7 +208,7 @@ armpmu_del(struct perf_event *event, int flags)
hw_events->events[idx] = NULL;
clear_bit(idx, hw_events->used_mask);
if (armpmu->clear_event_idx)
- armpmu->clear_event_idx(event);
+ armpmu->clear_event_idx(hw_events, event);
perf_event_update_userpage(event);
}
@@ -1483,9 +1483,6 @@ static int armv7_a7_pmu_init(struct arm_pmu *cpu_pmu)
#define VENUM_EVENT (2 << 16)
#define KRAIT_EVENT_MASK (KRAIT_EVENT | VENUM_EVENT)
#define PMRESRn_EN BIT(31)
-#define NUM_PMRESR (KRAIT_VPMRESR0_GROUP0 + 4 - KRAIT_PMRESR0_GROUP0)
-
-static DEFINE_PER_CPU(unsigned long [BITS_TO_LONGS(NUM_PMRESR)], pmresrn_used);
static u32 krait_read_pmresrn(int n)
{
@@ -1542,6 +1539,7 @@ static void krait_pre_vpmresr0(u32 *venum_orig_val, u32 *fp_orig_val)
u32 venum_new_val;
u32 fp_new_val;
+ BUG_ON(preemptible());
/* CPACR Enable CP10 and CP11 access */
*venum_orig_val = get_copro_access();
venum_new_val = *venum_orig_val | CPACC_SVC(10) | CPACC_SVC(11);
@@ -1555,6 +1553,7 @@ static void krait_pre_vpmresr0(u32 *venum_orig_val, u32 *fp_orig_val)
static void krait_post_vpmresr0(u32 venum_orig_val, u32 fp_orig_val)
{
+ BUG_ON(preemptible());
/* Restore FPEXC */
fmxr(FPEXC, fp_orig_val);
isb();
@@ -1750,7 +1749,6 @@ static int krait_pmu_get_event_idx(struct pmu_hw_events *cpuc,
unsigned int group;
bool krait_event;
struct hw_perf_event *hwc = &event->hw;
- unsigned long *bitmap = this_cpu_ptr(pmresrn_used);
region = (hwc->config_base >> 12) & 0xf;
code = (hwc->config_base >> 4) & 0xff;
@@ -1773,26 +1771,27 @@ static int krait_pmu_get_event_idx(struct pmu_hw_events *cpuc,
bit = krait_get_pmresrn_event(region);
bit -= krait_get_pmresrn_event(0);
bit += group;
+ bit <<= 16; /* Use the upper 16 bits of the used_mask */
- if (test_and_set_bit(bit, bitmap))
+ if (test_and_set_bit(bit, cpuc->used_mask))
return -EAGAIN;
}
idx = armv7pmu_get_event_idx(cpuc, event);
if (idx < 0 && krait_event)
- clear_bit(bit, bitmap);
+ clear_bit(bit, cpuc->used_mask);
return idx;
}
-static void krait_pmu_clear_event_idx(struct perf_event *event)
+static void krait_pmu_clear_event_idx(struct pmu_hw_events *cpuc,
+ struct perf_event *event)
{
int bit;
struct hw_perf_event *hwc = &event->hw;
unsigned int region;
unsigned int group;
bool krait_event;
- unsigned long *bitmap = this_cpu_ptr(pmresrn_used);
region = (hwc->config_base >> 12) & 0xf;
group = (hwc->config_base >> 0) & 0xf;
@@ -1805,7 +1804,8 @@ static void krait_pmu_clear_event_idx(struct perf_event *event)
bit = krait_get_pmresrn_event(region);
bit -= krait_get_pmresrn_event(0);
bit += group;
- clear_bit(bit, bitmap);
+ bit <<= 16;
+ clear_bit(bit, cpuc->used_mask);
}
}