mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 03:11:11 -04:00
Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull arm64 MPAM fixes from Catalin Marinas: - Fix NULL dereference and a false-positive warning when the driver probes hardware with surprising version numbers - Fix writing values to the wrong registers when probing cache-utilisation counters. Replace 'NRDY' probing with a version that is robust for platforms where the bit is writeable by both hardware and software * tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: arm_mpam: Check whether the config array is allocated before destroying it arm_mpam: Fix false positive assert failure during mpam_disable() arm_mpam: Improve check for whether or not NRDY is hardware managed arm_mpam: Pretend that NRDY is always hardware managed arm_mpam: Fix monitor instance selection when checking for hardware NRDY
This commit is contained in:
@@ -164,11 +164,17 @@ static void mpam_free_garbage(void)
|
||||
/*
|
||||
* Once mpam is enabled, new requestors cannot further reduce the available
|
||||
* partid. Assert that the size is fixed, and new requestors will be turned
|
||||
* away.
|
||||
* away. This is needed when walking over structures sized by PARTID.
|
||||
*
|
||||
* During mpam_disable() these structures are not fixed, but the MSC state
|
||||
* is still reset using whatever sizes have been discovered so far. As only
|
||||
* PARTID 0 will be used after mpam_disable(), any race would be benign.
|
||||
* Skip the check if a mpam_disable_reason has been set.
|
||||
*/
|
||||
static void mpam_assert_partid_sizes_fixed(void)
|
||||
{
|
||||
WARN_ON_ONCE(!partid_max_published);
|
||||
if (!mpam_disable_reason)
|
||||
WARN_ON_ONCE(!partid_max_published);
|
||||
}
|
||||
|
||||
static u32 __mpam_read_reg(struct mpam_msc *msc, u16 reg)
|
||||
@@ -728,10 +734,9 @@ static void mpam_enable_quirks(struct mpam_msc *msc)
|
||||
* Try and see what values stick in this bit. If we can write either value,
|
||||
* its probably not implemented by hardware.
|
||||
*/
|
||||
static bool _mpam_ris_hw_probe_hw_nrdy(struct mpam_msc_ris *ris, u32 mon_reg)
|
||||
static bool mpam_ris_hw_probe_csu_nrdy(struct mpam_msc_ris *ris)
|
||||
{
|
||||
u32 now;
|
||||
u64 mon_sel;
|
||||
u32 now, mon_sel, ctl_val;
|
||||
bool can_set, can_clear;
|
||||
struct mpam_msc *msc = ris->vmsc->msc;
|
||||
|
||||
@@ -740,23 +745,30 @@ static bool _mpam_ris_hw_probe_hw_nrdy(struct mpam_msc_ris *ris, u32 mon_reg)
|
||||
|
||||
mon_sel = FIELD_PREP(MSMON_CFG_MON_SEL_MON_SEL, 0) |
|
||||
FIELD_PREP(MSMON_CFG_MON_SEL_RIS, ris->ris_idx);
|
||||
_mpam_write_monsel_reg(msc, mon_reg, mon_sel);
|
||||
mpam_write_monsel_reg(msc, CFG_MON_SEL, mon_sel);
|
||||
|
||||
_mpam_write_monsel_reg(msc, mon_reg, MSMON___NRDY);
|
||||
now = _mpam_read_monsel_reg(msc, mon_reg);
|
||||
/* Hardware might ignore nrdy if it's not enabled */
|
||||
ctl_val = MSMON_CFG_CSU_CTL_TYPE_CSU;
|
||||
ctl_val |= MSMON_CFG_x_CTL_MATCH_PARTID;
|
||||
ctl_val |= MSMON_CFG_x_CTL_MATCH_PMG;
|
||||
ctl_val |= MSMON_CFG_x_CTL_EN;
|
||||
mpam_write_monsel_reg(msc, CFG_CSU_FLT, 0);
|
||||
mpam_write_monsel_reg(msc, CFG_CSU_CTL, ctl_val);
|
||||
|
||||
_mpam_write_monsel_reg(msc, MSMON_CSU, MSMON___NRDY);
|
||||
now = _mpam_read_monsel_reg(msc, MSMON_CSU);
|
||||
can_set = now & MSMON___NRDY;
|
||||
|
||||
_mpam_write_monsel_reg(msc, mon_reg, 0);
|
||||
now = _mpam_read_monsel_reg(msc, mon_reg);
|
||||
_mpam_write_monsel_reg(msc, MSMON_CSU, 0);
|
||||
/* Configuration change to try and coax hardware into setting nrdy */
|
||||
mpam_write_monsel_reg(msc, CFG_CSU_FLT, 0x1);
|
||||
now = _mpam_read_monsel_reg(msc, MSMON_CSU);
|
||||
can_clear = !(now & MSMON___NRDY);
|
||||
mpam_mon_sel_unlock(msc);
|
||||
|
||||
return (!can_set || !can_clear);
|
||||
}
|
||||
|
||||
#define mpam_ris_hw_probe_hw_nrdy(_ris, _mon_reg) \
|
||||
_mpam_ris_hw_probe_hw_nrdy(_ris, MSMON_##_mon_reg)
|
||||
|
||||
static void mpam_ris_hw_probe(struct mpam_msc_ris *ris)
|
||||
{
|
||||
int err;
|
||||
@@ -873,20 +885,18 @@ static void mpam_ris_hw_probe(struct mpam_msc_ris *ris)
|
||||
mpam_set_feature(mpam_feat_msmon_csu_xcl, props);
|
||||
|
||||
/* Is NRDY hardware managed? */
|
||||
hw_managed = mpam_ris_hw_probe_hw_nrdy(ris, CSU);
|
||||
if (hw_managed)
|
||||
mpam_set_feature(mpam_feat_msmon_csu_hw_nrdy, props);
|
||||
}
|
||||
hw_managed = mpam_ris_hw_probe_csu_nrdy(ris);
|
||||
|
||||
/*
|
||||
* Accept the missing firmware property if NRDY appears
|
||||
* un-implemented.
|
||||
*/
|
||||
if (err && mpam_has_feature(mpam_feat_msmon_csu_hw_nrdy, props))
|
||||
dev_err_once(dev, "Counters are not usable because not-ready timeout was not provided by firmware.");
|
||||
/*
|
||||
* Accept the missing firmware property if NRDY appears
|
||||
* un-implemented.
|
||||
*/
|
||||
if (err && hw_managed)
|
||||
dev_err_once(dev, "Counters are not usable because not-ready timeout was not provided by firmware.");
|
||||
}
|
||||
}
|
||||
if (FIELD_GET(MPAMF_MSMON_IDR_MSMON_MBWU, msmon_features)) {
|
||||
bool has_long, hw_managed;
|
||||
bool has_long;
|
||||
u32 mbwumon_idr = mpam_read_partsel_reg(msc, MBWUMON_IDR);
|
||||
|
||||
props->num_mbwu_mon = FIELD_GET(MPAMF_MBWUMON_IDR_NUM_MON, mbwumon_idr);
|
||||
@@ -905,16 +915,6 @@ static void mpam_ris_hw_probe(struct mpam_msc_ris *ris)
|
||||
} else {
|
||||
mpam_set_feature(mpam_feat_msmon_mbwu_31counter, props);
|
||||
}
|
||||
|
||||
/* Is NRDY hardware managed? */
|
||||
hw_managed = mpam_ris_hw_probe_hw_nrdy(ris, MBWU);
|
||||
if (hw_managed)
|
||||
mpam_set_feature(mpam_feat_msmon_mbwu_hw_nrdy, props);
|
||||
|
||||
/*
|
||||
* Don't warn about any missing firmware property for
|
||||
* MBWU NRDY - it doesn't make any sense!
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1197,7 +1197,6 @@ static void __ris_msmon_read(void *arg)
|
||||
bool reset_on_next_read = false;
|
||||
struct mpam_msc_ris *ris = m->ris;
|
||||
struct msmon_mbwu_state *mbwu_state;
|
||||
struct mpam_props *rprops = &ris->props;
|
||||
struct mpam_msc *msc = m->ris->vmsc->msc;
|
||||
u32 mon_sel, ctl_val, flt_val, cur_ctl, cur_flt;
|
||||
|
||||
@@ -1253,8 +1252,7 @@ static void __ris_msmon_read(void *arg)
|
||||
switch (m->type) {
|
||||
case mpam_feat_msmon_csu:
|
||||
now = mpam_read_monsel_reg(msc, CSU);
|
||||
if (mpam_has_feature(mpam_feat_msmon_csu_hw_nrdy, rprops))
|
||||
nrdy = now & MSMON___NRDY;
|
||||
nrdy = now & MSMON___NRDY;
|
||||
now = FIELD_GET(MSMON___VALUE, now);
|
||||
|
||||
if (mpam_has_quirk(IGNORE_CSU_NRDY, msc) && m->waited_timeout)
|
||||
@@ -1266,8 +1264,7 @@ static void __ris_msmon_read(void *arg)
|
||||
case mpam_feat_msmon_mbwu_63counter:
|
||||
if (m->type != mpam_feat_msmon_mbwu_31counter) {
|
||||
now = mpam_msc_read_mbwu_l(msc);
|
||||
if (mpam_has_feature(mpam_feat_msmon_mbwu_hw_nrdy, rprops))
|
||||
nrdy = now & MSMON___L_NRDY;
|
||||
nrdy = now & MSMON___L_NRDY;
|
||||
|
||||
if (m->type == mpam_feat_msmon_mbwu_63counter)
|
||||
now = FIELD_GET(MSMON___LWD_VALUE, now);
|
||||
@@ -1275,8 +1272,7 @@ static void __ris_msmon_read(void *arg)
|
||||
now = FIELD_GET(MSMON___L_VALUE, now);
|
||||
} else {
|
||||
now = mpam_read_monsel_reg(msc, MBWU);
|
||||
if (mpam_has_feature(mpam_feat_msmon_mbwu_hw_nrdy, rprops))
|
||||
nrdy = now & MSMON___NRDY;
|
||||
nrdy = now & MSMON___NRDY;
|
||||
now = FIELD_GET(MSMON___VALUE, now);
|
||||
}
|
||||
|
||||
@@ -2585,6 +2581,9 @@ static void __destroy_component_cfg(struct mpam_component *comp)
|
||||
|
||||
lockdep_assert_held(&mpam_list_lock);
|
||||
|
||||
if (!comp->cfg)
|
||||
return;
|
||||
|
||||
add_to_garbage(comp->cfg);
|
||||
list_for_each_entry(vmsc, &comp->vmsc, comp_list) {
|
||||
msc = vmsc->msc;
|
||||
|
||||
@@ -181,14 +181,12 @@ enum mpam_device_features {
|
||||
mpam_feat_msmon_csu,
|
||||
mpam_feat_msmon_csu_capture,
|
||||
mpam_feat_msmon_csu_xcl,
|
||||
mpam_feat_msmon_csu_hw_nrdy,
|
||||
mpam_feat_msmon_mbwu,
|
||||
mpam_feat_msmon_mbwu_31counter,
|
||||
mpam_feat_msmon_mbwu_44counter,
|
||||
mpam_feat_msmon_mbwu_63counter,
|
||||
mpam_feat_msmon_mbwu_capture,
|
||||
mpam_feat_msmon_mbwu_rwbw,
|
||||
mpam_feat_msmon_mbwu_hw_nrdy,
|
||||
mpam_feat_partid_nrw,
|
||||
MPAM_FEATURE_LAST
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user