summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorPawan Gupta <pawan.kumar.gupta@linux.intel.com>2022-04-04 17:34:19 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-04-20 09:06:44 +0200
commitc30aba88776ffb3344be8156bad9bd615a31cd11 (patch)
tree64e9974d1e3fb6899f9f88b4921b817ac3f29412 /arch
parent8510c2346d9e47a72b7f018a36ef0c39483e53d6 (diff)
downloadlinux-c30aba88776ffb3344be8156bad9bd615a31cd11.tar.gz
linux-c30aba88776ffb3344be8156bad9bd615a31cd11.tar.bz2
linux-c30aba88776ffb3344be8156bad9bd615a31cd11.zip
x86/pm: Save the MSR validity status at context setup
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>
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/power/cpu.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/arch/x86/power/cpu.c b/arch/x86/power/cpu.c
index c8f947a4aaf2..af2646e38e63 100644
--- a/arch/x86/power/cpu.c
+++ b/arch/x86/power/cpu.c
@@ -41,7 +41,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++;
}
}
@@ -419,8 +420,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;