hulk inclusion category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I7PP9I
--------------------------------
When a CPU is suspended (either through suspend-to-RAM or CPUidle), The content of MPAM context registers can be lost, as PARTID and PMG is reserved already in this-cpu variable pqr_state, so restore it on power-up process.
Signed-off-by: Wang ShaoBo bobo.shaobowang@huawei.com --- arch/arm64/kernel/mpam/mpam_device.c | 27 ++++++++++++++++++++++++++ arch/arm64/kernel/mpam/mpam_internal.h | 2 ++ arch/arm64/kernel/mpam/mpam_resctrl.c | 10 ++++++++++ 3 files changed, 39 insertions(+)
diff --git a/arch/arm64/kernel/mpam/mpam_device.c b/arch/arm64/kernel/mpam/mpam_device.c index 66d787f134c0e..06e8afadd149e 100644 --- a/arch/arm64/kernel/mpam/mpam_device.c +++ b/arch/arm64/kernel/mpam/mpam_device.c @@ -35,6 +35,7 @@ #include <linux/of.h> #include <linux/of_platform.h> #include <linux/of_address.h> +#include <linux/cpu_pm.h>
#include "mpam_resource.h" #include "mpam_device.h" @@ -532,6 +533,30 @@ static void mpam_disable_irqs(void) } }
+static struct notifier_block mpam_notifier_block; +static int cpu_pm_mpam_notify(struct notifier_block *b, + unsigned long cmd, void *v) +{ + switch (cmd) { + case CPU_PM_ENTER: + break; + case CPU_PM_EXIT: + case CPU_PM_ENTER_FAILED: + mpam_restore_context(); + break; + default: + return NOTIFY_DONE; + } + + return NOTIFY_OK; +} + +static int cpu_pm_mpam_register(void) +{ + mpam_notifier_block.notifier_call = cpu_pm_mpam_notify; + return cpu_pm_register_notifier(&mpam_notifier_block); +} + /* * Enable mpam once all devices have been probed. * Scheduled by mpam_discovery_complete() once all devices have been created. @@ -603,6 +628,8 @@ static void mpam_enable(struct work_struct *work) if (mpam_cpuhp_state <= 0) pr_err("Failed to re-register 'dyn' cpuhp callbacks"); mutex_unlock(&mpam_cpuhp_lock); + + cpu_pm_mpam_register(); }
static void mpam_failed(struct work_struct *work) diff --git a/arch/arm64/kernel/mpam/mpam_internal.h b/arch/arm64/kernel/mpam/mpam_internal.h index 7b84ea54975aa..1ba355988b2c4 100644 --- a/arch/arm64/kernel/mpam/mpam_internal.h +++ b/arch/arm64/kernel/mpam/mpam_internal.h @@ -342,4 +342,6 @@ int rmid_mon_ptrs_init(u32 nr_rmids); struct resctrl_resource * mpam_resctrl_get_resource(enum resctrl_resource_level level);
+void mpam_restore_context(void); + #endif diff --git a/arch/arm64/kernel/mpam/mpam_resctrl.c b/arch/arm64/kernel/mpam/mpam_resctrl.c index 4a1e376ec4970..af5b52c3ad417 100644 --- a/arch/arm64/kernel/mpam/mpam_resctrl.c +++ b/arch/arm64/kernel/mpam/mpam_resctrl.c @@ -2272,6 +2272,16 @@ void __mpam_sched_in(void) } }
+void mpam_restore_context(void) +{ + struct intel_pqr_state *state = this_cpu_ptr(&pqr_state); + + state->cur_rmid = 0; + state->cur_closid = 0; + + mpam_sched_in(); +} + static void mpam_update_from_resctrl_cfg(struct mpam_resctrl_res *res, u32 resctrl_cfg, enum rdt_event_id evt,