From: Alexey Kardashevskiy <aik@amd.com>
To: <kvm@vger.kernel.org>
Cc: <x86@kernel.org>, <linux-kernel@vger.kernel.org>,
Venu Busireddy <venu.busireddy@oracle.com>,
Tony Luck <tony.luck@intel.com>,
Tom Lendacky <thomas.lendacky@amd.com>,
Thomas Gleixner <tglx@linutronix.de>,
"Sean Christopherson" <seanjc@google.com>,
Sandipan Das <sandipan.das@amd.com>,
Peter Zijlstra <peterz@infradead.org>,
Pawan Gupta <pawan.kumar.gupta@linux.intel.com>,
Paolo Bonzini <pbonzini@redhat.com>,
Michael Roth <michael.roth@amd.com>,
Mario Limonciello <mario.limonciello@amd.com>,
Jan Kara <jack@suse.cz>, Ingo Molnar <mingo@redhat.com>,
Huang Rui <ray.huang@amd.com>,
Dave Hansen <dave.hansen@linux.intel.com>,
Daniel Sneddon <daniel.sneddon@linux.intel.com>,
Brijesh Singh <brijesh.singh@amd.com>,
Borislav Petkov <bp@alien8.de>,
Arnaldo Carvalho de Melo <acme@redhat.com>,
Andrew Cooper <andrew.cooper3@citrix.com>,
Alexander Shishkin <alexander.shishkin@linux.intel.com>,
Adrian Hunter <adrian.hunter@intel.com>,
"Jason A. Donenfeld" <Jason@zx2c4.com>,
"H. Peter Anvin" <hpa@zytor.com>,
Alexey Kardashevskiy <aik@amd.com>
Subject: [PATCH kernel v2 1/3] x86/amd: Cache values in percpu variables
Date: Fri, 9 Dec 2022 15:38:02 +1100 [thread overview]
Message-ID: <20221209043804.942352-2-aik@amd.com> (raw)
In-Reply-To: <20221209043804.942352-1-aik@amd.com>
Reading DR[0-3]_ADDR_MASK MSRs takes about 250 cycles which is going to
be noticeable with the AMD KVM SEV-ES DebugSwap feature enabled.
KVM is going to store host's DR[0-3] and DR[0-3]_ADDR_MASK before
switching to a guest; the hardware is going to swap these on VMRUN
and VMEXIT.
Store MSR values passsed to set_dr_addr_mask() in percpu values
(when changed) and return them via new amd_get_dr_addr_mask().
The gain here is about 10x.
As amd_set_dr_addr_mask() uses the array too, change the @dr type to
unsigned to avoid checking for <0.
While at it, replace deprecated boot_cpu_has() with cpu_feature_enabled()
in set_dr_addr_mask().
Signed-off-by: Alexey Kardashevskiy <aik@amd.com>
---
Changes:
v2:
* reworked to use arrays
* set() skips wrmsr() when the mask is not changed
* added stub for get_dr_addr_mask()
* changed @dr type to unsigned
* s/boot_cpu_has/cpu_feature_enabled/
* added amd_ prefix
---
arch/x86/include/asm/debugreg.h | 9 +++-
arch/x86/kernel/cpu/amd.c | 45 ++++++++++++++------
2 files changed, 38 insertions(+), 16 deletions(-)
diff --git a/arch/x86/include/asm/debugreg.h b/arch/x86/include/asm/debugreg.h
index cfdf307ddc01..59f97ba25d5f 100644
--- a/arch/x86/include/asm/debugreg.h
+++ b/arch/x86/include/asm/debugreg.h
@@ -126,9 +126,14 @@ static __always_inline void local_db_restore(unsigned long dr7)
}
#ifdef CONFIG_CPU_SUP_AMD
-extern void set_dr_addr_mask(unsigned long mask, int dr);
+extern void set_dr_addr_mask(unsigned long mask, unsigned int dr);
+extern unsigned long amd_get_dr_addr_mask(unsigned int dr);
#else
-static inline void set_dr_addr_mask(unsigned long mask, int dr) { }
+static inline void set_dr_addr_mask(unsigned long mask, unsigned int dr) { }
+static inline unsigned long amd_get_dr_addr_mask(unsigned int dr)
+{
+ return 0;
+}
#endif
#endif /* _ASM_X86_DEBUGREG_H */
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index c75d75b9f11a..9ac5a19f89b9 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -1158,24 +1158,41 @@ static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum)
return false;
}
-void set_dr_addr_mask(unsigned long mask, int dr)
+DEFINE_PER_CPU_READ_MOSTLY(unsigned long[4], amd_dr_addr_mask);
+
+static unsigned int amd_msr_dr_addr_masks[] = {
+ MSR_F16H_DR0_ADDR_MASK,
+ MSR_F16H_DR1_ADDR_MASK - 1 + 1,
+ MSR_F16H_DR1_ADDR_MASK - 1 + 2,
+ MSR_F16H_DR1_ADDR_MASK - 1 + 3
+};
+
+void set_dr_addr_mask(unsigned long mask, unsigned int dr)
{
- if (!boot_cpu_has(X86_FEATURE_BPEXT))
+ if (!cpu_feature_enabled(X86_FEATURE_BPEXT))
return;
- switch (dr) {
- case 0:
- wrmsr(MSR_F16H_DR0_ADDR_MASK, mask, 0);
- break;
- case 1:
- case 2:
- case 3:
- wrmsr(MSR_F16H_DR1_ADDR_MASK - 1 + dr, mask, 0);
- break;
- default:
- break;
- }
+ if (WARN_ON_ONCE(dr >= ARRAY_SIZE(amd_msr_dr_addr_masks)))
+ return;
+
+ if (per_cpu(amd_dr_addr_mask, smp_processor_id())[dr] == mask)
+ return;
+
+ wrmsr(amd_msr_dr_addr_masks[dr], mask, 0);
+ per_cpu(amd_dr_addr_mask, smp_processor_id())[dr] = mask;
+}
+
+unsigned long amd_get_dr_addr_mask(unsigned int dr)
+{
+ if (!cpu_feature_enabled(X86_FEATURE_BPEXT))
+ return 0;
+
+ if (WARN_ON_ONCE(dr >= ARRAY_SIZE(amd_msr_dr_addr_masks)))
+ return 0;
+
+ return per_cpu(amd_dr_addr_mask[dr], smp_processor_id());
}
+EXPORT_SYMBOL_GPL(amd_get_dr_addr_mask);
u32 amd_get_highest_perf(void)
{
--
2.38.1
next prev parent reply other threads:[~2022-12-09 4:39 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-09 4:38 [PATCH kernel v2 0/3] KVM: SEV: Enable AMD SEV-ES DebugSwap Alexey Kardashevskiy
2022-12-09 4:38 ` Alexey Kardashevskiy [this message]
2023-01-10 16:05 ` [PATCH kernel v2 1/3] x86/amd: Cache values in percpu variables Borislav Petkov
2023-01-12 5:21 ` Alexey Kardashevskiy
2023-01-12 11:12 ` Borislav Petkov
2022-12-09 4:38 ` [PATCH kernel v2 2/3] KVM: SEV: Enable data breakpoints in SEV-ES Alexey Kardashevskiy
2023-01-10 18:00 ` Borislav Petkov
2023-01-10 19:06 ` Tom Lendacky
2023-01-12 5:45 ` Alexey Kardashevskiy
2023-01-12 11:28 ` Borislav Petkov
2023-01-12 14:32 ` Tom Lendacky
2022-12-09 4:38 ` [PATCH kernel v2 3/3] x86/sev: Do not handle #VC for DR7 read/write Alexey Kardashevskiy
2023-01-10 20:04 ` Borislav Petkov
2023-01-09 5:20 ` [PATCH kernel v2 0/3] KVM: SEV: Enable AMD SEV-ES DebugSwap Alexey Kardashevskiy
2023-01-10 17:41 ` Borislav Petkov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221209043804.942352-2-aik@amd.com \
--to=aik@amd.com \
--cc=Jason@zx2c4.com \
--cc=acme@redhat.com \
--cc=adrian.hunter@intel.com \
--cc=alexander.shishkin@linux.intel.com \
--cc=andrew.cooper3@citrix.com \
--cc=bp@alien8.de \
--cc=brijesh.singh@amd.com \
--cc=daniel.sneddon@linux.intel.com \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=jack@suse.cz \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mario.limonciello@amd.com \
--cc=michael.roth@amd.com \
--cc=mingo@redhat.com \
--cc=pawan.kumar.gupta@linux.intel.com \
--cc=pbonzini@redhat.com \
--cc=peterz@infradead.org \
--cc=ray.huang@amd.com \
--cc=sandipan.das@amd.com \
--cc=seanjc@google.com \
--cc=tglx@linutronix.de \
--cc=thomas.lendacky@amd.com \
--cc=tony.luck@intel.com \
--cc=venu.busireddy@oracle.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.