From: Pawan Gupta pawan.kumar.gupta@linux.intel.com
stable inclusion from stable-4.19.238 commit c7daf1b4ad809692d5c26f33c02ed8a031066548 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I5X41F CVE: NA
--------------------------------
commit 73924ec4d560257004d5b5116b22a3647661e364 upstream.
The mechanism to save/restore MSRs during S3 suspend/resume checks for the MSR validity during suspend, and only restores the MSR if its a valid MSR. This is not optimal, as an invalid MSR will unnecessarily throw an exception for every suspend cycle. The more invalid MSRs, higher the impact will be.
Check and save the MSR validity at setup. This ensures that only valid MSRs that are guaranteed to not throw an exception will be attempted during suspend.
Fixes: 7a9c2dd08ead ("x86/pm: Introduce quirk framework to save/restore extra MSR registers around suspend/resume") Suggested-by: Dave Hansen dave.hansen@linux.intel.com Signed-off-by: Pawan Gupta pawan.kumar.gupta@linux.intel.com Reviewed-by: Dave Hansen dave.hansen@linux.intel.com Acked-by: Borislav Petkov bp@suse.de Cc: stable@vger.kernel.org Signed-off-by: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Lin Yujun linyujun809@huawei.com Reviewed-by: Zhang Jianhua chris.zjh@huawei.com Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com --- arch/x86/power/cpu.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c index df00425677a5..794824948263 100644 --- a/arch/x86/power/cpu.c +++ b/arch/x86/power/cpu.c @@ -42,7 +42,8 @@ static void msr_save_context(struct saved_context *ctxt) struct saved_msr *end = msr + ctxt->saved_msrs.num;
while (msr < end) { - msr->valid = !rdmsrl_safe(msr->info.msr_no, &msr->info.reg.q); + if (msr->valid) + rdmsrl(msr->info.msr_no, msr->info.reg.q); msr++; } } @@ -434,8 +435,10 @@ static int msr_build_context(const u32 *msr_id, const int num) }
for (i = saved_msrs->num, j = 0; i < total_num; i++, j++) { + u64 dummy; + msr_array[i].info.msr_no = msr_id[j]; - msr_array[i].valid = false; + msr_array[i].valid = !rdmsrl_safe(msr_id[j], &dummy); msr_array[i].info.reg.q = 0; } saved_msrs->num = total_num;