提交 675345bc 编写于 作者: J James Morse 提交者: Zheng Zengkai

arm64/mpam: Reset controls when CPUs come online

hulk inclusion
category: feature
feature: ARM MPAM support
bugzilla: 48265
CVE: NA

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

As only the hardware's default partid has its configuration reset
in hardware, we have to do all the others in software.

If this cpu coming online has made a new device accessible, reset it.
For cpuhp we assume its configuration has been lost.

Write the maximum values for all discovered controls.

[Wang ShaoBo: few version adaption changes]
Signed-off-by: NJames Morse <james.morse@arm.com>
Link: http://www.linux-arm.org/git?p=linux-jm.git;a=patch;h=a6160f572b09dceb6bd65f15a30f47e6a0fe7f4eSigned-off-by: NWang ShaoBo <bobo.shaobowang@huawei.com>
Reviewed-by: NXiongfeng Wang <wangxiongfeng2@huawei.com>
Reviewed-by: NCheng Jian <cj.chengjian@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 3e04af4e
...@@ -72,6 +72,7 @@ ...@@ -72,6 +72,7 @@
#define BWA_WD 6 /* hard code for P680 */ #define BWA_WD 6 /* hard code for P680 */
#define MBW_MAX_MASK 0xFC00 #define MBW_MAX_MASK 0xFC00
#define MBW_MAX_HARDLIM BIT(31) #define MBW_MAX_HARDLIM BIT(31)
#define MBW_MAX_BWA_FRACT(w) GENMASK(w - 1, 0)
#define MBW_MAX_SET(v) (MBW_MAX_HARDLIM|((v) << (16 - BWA_WD))) #define MBW_MAX_SET(v) (MBW_MAX_HARDLIM|((v) << (16 - BWA_WD)))
#define MBW_MAX_GET(v) (((v) & MBW_MAX_MASK) >> (16 - BWA_WD)) #define MBW_MAX_GET(v) (((v) & MBW_MAX_MASK) >> (16 - BWA_WD))
...@@ -85,6 +86,10 @@ ...@@ -85,6 +86,10 @@
#define MSMON_CFG_CSU_TYPE 0x43 #define MSMON_CFG_CSU_TYPE 0x43
#define MSMON_CFG_MBWU_TYPE 0x42 #define MSMON_CFG_MBWU_TYPE 0x42
/*
* Set MPAMCFG_PART_SEL internal bit
*/
#define PART_SEL_SET_INTERNAL(r) (r | BIT(16))
/* /*
* Size of the memory mapped registers: 4K of feature page then 2 x 4K * Size of the memory mapped registers: 4K of feature page then 2 x 4K
* bitmap registers * bitmap registers
......
...@@ -530,6 +530,91 @@ int __init mpam_discovery_start(void) ...@@ -530,6 +530,91 @@ int __init mpam_discovery_start(void)
return 0; return 0;
} }
static void mpam_reset_device_bitmap(struct mpam_device *dev, u16 reg, u16 wd)
{
u32 bm = ~0;
int i;
lockdep_assert_held(&dev->lock);
/* write all but the last full-32bit-word */
for (i = 0; i < wd / 32; i++, reg += sizeof(bm))
mpam_write_reg(dev, reg, bm);
/* and the last partial 32bit word */
bm = GENMASK(wd % 32, 0);
if (bm)
mpam_write_reg(dev, reg, bm);
}
static void mpam_reset_device_config(struct mpam_component *comp,
struct mpam_device *dev, u32 partid)
{
u16 intpri = GENMASK(dev->intpri_wd, 0);
u16 dspri = GENMASK(dev->dspri_wd, 0);
u32 pri_val = 0;
u32 mbw_max;
lockdep_assert_held(&dev->lock);
if (mpam_has_feature(mpam_feat_part_nrw, dev->features))
partid = PART_SEL_SET_INTERNAL(partid);
mpam_write_reg(dev, MPAMCFG_PART_SEL, partid);
wmb(); /* subsequent writes must be applied to our new partid */
if (mpam_has_feature(mpam_feat_cpor_part, dev->features))
mpam_reset_device_bitmap(dev, MPAMCFG_CPBM, dev->cpbm_wd);
if (mpam_has_feature(mpam_feat_mbw_part, dev->features))
mpam_reset_device_bitmap(dev, MPAMCFG_MBW_PBM,
dev->mbw_pbm_bits);
if (mpam_has_feature(mpam_feat_mbw_max, dev->features)) {
mbw_max = MBW_MAX_SET(MBW_MAX_BWA_FRACT(dev->bwa_wd));
mpam_write_reg(dev, MPAMCFG_MBW_MAX, mbw_max);
}
if (mpam_has_feature(mpam_feat_mbw_min, dev->features)) {
mpam_write_reg(dev, MPAMCFG_MBW_MIN, 0);
}
if (mpam_has_feature(mpam_feat_intpri_part, dev->features) ||
mpam_has_feature(mpam_feat_dspri_part, dev->features)) {
/* aces high? */
if (!mpam_has_feature(mpam_feat_intpri_part_0_low,
dev->features))
intpri = 0;
if (!mpam_has_feature(mpam_feat_dspri_part_0_low,
dev->features))
dspri = 0;
if (mpam_has_feature(mpam_feat_intpri_part, dev->features))
pri_val |= intpri;
if (mpam_has_feature(mpam_feat_dspri_part, dev->features))
pri_val |= (dspri << MPAMCFG_PRI_DSPRI_SHIFT);
mpam_write_reg(dev, MPAMCFG_PRI, pri_val);
}
mb(); /* complete the configuration before the cpu can use this partid */
}
/*
* Called from cpuhp callbacks and with the cpus_read_lock() held from
* mpam_reset_devices().
*/
static void mpam_reset_device(struct mpam_component *comp,
struct mpam_device *dev)
{
u32 partid;
lockdep_assert_held(&dev->lock);
if (!mpam_has_feature(mpam_feat_part_nrw, dev->features)) {
for (partid = 0; partid < dev->num_partid; partid++)
mpam_reset_device_config(comp, dev, partid);
} else {
for (partid = 0; partid < dev->num_intpartid; partid++)
mpam_reset_device_config(comp, dev, partid);
}
}
static int __online_devices(struct mpam_component *comp, int cpu) static int __online_devices(struct mpam_component *comp, int cpu)
{ {
int err = 0; int err = 0;
...@@ -548,6 +633,9 @@ static int __online_devices(struct mpam_component *comp, int cpu) ...@@ -548,6 +633,9 @@ static int __online_devices(struct mpam_component *comp, int cpu)
new_device_probed = true; new_device_probed = true;
} }
if (!err && cpumask_empty(&dev->online_affinity))
mpam_reset_device(comp, dev);
cpumask_set_cpu(cpu, &dev->online_affinity); cpumask_set_cpu(cpu, &dev->online_affinity);
spin_unlock_irqrestore(&dev->lock, flags); spin_unlock_irqrestore(&dev->lock, flags);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册